持久化方案
Android系统中主要提供了3种方式用于简单地实现数据持久化功能:文件存储、SharedPreferences存储以及数据库存储。
文件存储
核心技术就是Context类中提供的openFileInput()和openFileOutput()方法,之后就是利用各种流来进行读写操作。
写入数据
- 创建openFileOutput()方法,可以用于将数据存储到指定的文件中;
- 构建出一个OutputStreamWriter对象,接着再使用OutputStreamWriter构建出一个BufferedWriter对象;
- 使用一个use函数,保证在Lambda 表达式中的代码全部执行完之后自动将外层的流关闭,不需要我们手动去关闭流。
文件名不可以包含路径,因为所有的文件都默认存储到/data/data/<package name>/files/目录下。
使用“Device File Explorer”可以查看设备文件。
读取数据
- 使用openFileInput()函数进行读取,并返回一个FileInputStream对象;
- 构建出一个InputStreamReader对象,接着再使用InputStreamReader构建出一个BufferedReader对象;
- 使用一个use函数,通过BufferedReader将文件中的数据一行行读取出来。
SharedPreferences 存储
SharedPreferences是使用键值对的方式来存储数据的。
存储
SharedPreferences文件都是存放在/data/data/<package name>/shared_prefs/目录下的。
- 首先需要获取SharedPreferences对象;
- 调用SharedPreferences对象的edit()方法获取一个SharedPreferences.Editor对象;
- 向SharedPreferences.Editor对象中添加数据,比如添加一个布尔型数据就使用putBoolean()方法,添加一个字符串则使用putString()方法,以此类推;
- 调用apply()方法将添加的数据提交,从而完成数据存储操作。
1 | class MainActivity : AppCompatActivity() { |
读取
- 首先通过getSharedPreferences()方法得到SharedPreferences对象;
- 然后分别调用它的getString()、getInt()和getBoolean()等方法即可获取数据。
SQLite 数据库存储
安装Database Navigator插件工具。
创建数据库
提供了一个SQLiteOpenHelper帮助类,借助这个类可以非常简单地对数据库进行创建和升级。
继承SQLiteOpenHelper抽象类,重写SQLiteOpenHelper中两个抽象方法:onCreate()和onUpgrade();
1 | class MyDatabaseHelper(val context: Context, name: String, version: Int) : |
添加数据
操作数据有两种方案,一种是使用SQL语句,一种是使用Android提供的封装函数。
使用SQL语句:除了查询数据的时候调用的是SQLiteDatabase的rawQuery()方法,其他操作都是调用的execSQL()方法。
使用SQLiteDatabase对象,借助这个对象可以对数据进行CRUD操作:
SQLiteDatabase中提供了一个insert()方法,专门用于添加数据;
SQLiteDatabase中提供了一个非常好用的update()方法,用于对数据进行更新;
SQLiteDatabase中提供了一个delete()方法,专门用于删除数据;
SQLiteDatabase中还提供了一个query()方法用于对数据进行查询,这个方法的参数非常复杂,最短的一个方法重载也需要传入7个参数。
使用事务
事务的特性可以保证让一系列的操作要么全部完成,要么一个都不会完成
- 首先调用SQLiteDatabase的beginTransaction()方法开启一个事务;
- 然后在一个异常捕获的代码块中执行具体的数据库操作;
- 当所有的操作都完成之后,调用setTransactionSuccessful()表示事务已经执行成功了;
- 最后在finally代码块中调用endTransaction()结束事务。
升级数据库的最佳写法的本质就是使用小于等于符号判定版本,并写若干个if语句。
Kotlin课堂
简化SharedPreferences 的用法
1 | fun SharedPreferences.edit(block: SharedPreferences.Editor.() -> Unit) { |
其实Google提供的KTX扩展库中已经包含了上述 SharedPreferences的简化用法。
简化ContentValues 的用法
在Kotlin中使用A to B这样的语法结构会创建一个Pair对象。
使用vararg关键字,指可变参数列表,我们允许向这个方法传入任意多个参数,这些参数都会被赋值到使用vararg声明的这一个变量上面,然后使用for-in循环可以将传入的所有参数遍历出来。
1 | fun cvOf(vararg pairs: Pair<String, Any?>): ContentValues { |
Kotlin中的Smart Cast功能。比如when语句进入Int条件分支后,这个条件下面的value会被自动转换成Int类型,而不再是Any?类型。
KTX库中也提供 了一个具有同样功能的contentValuesOf()方法:
1 | val values = contentValuesOf("name" to "Game of Thrones", "author" to "George Martin", |