简化SharedPreferences的用法
之前学的最原始的向SharedPreferences中存储数据的代码如下:
//获取SharedPreferences.Editor对象
val editor = getSharedPreferences("data",Context.MODE_PRIVATE).edit()
editor.putString("name","ZLS") //添加String类型数据
editor.putInt("age",18)
editor.putBoolean("married",false)
editor.apply() //提交数据
但在红色箭头所指的扩展库中,添加了他的简化用法

它包含了一段类似于下面的代码,可以大大方便SharedPreferences的使用
fun SharedPreferences.edit(block: SharedPreferences.Editor.() -> Unit){
val editor = edit()
editor.block()
editor.apply()
}
通过扩展函数的方式向SharedPreferences类中添加了一个edit函数,并且它还接收一个函数类型的参数,因此edit函数自然就是一个高阶函数了。 由于edit函数内拥有SharedPreferences的上下文,因此这里可以直接调用edit()方法来获取SharedPreferences.Editor对象。另外edit函数接收的是一个SharedPreferences.Editor的函数类型参数,因此这里需要调用editor.block()对函数类型参数进行调用,我们就可以在函数类型参数的具体实现中添加数据了。最后还要调用editor.apply()方法来提交数据,从而完成数据存储操作。
简化后使用代码如下:
getSharedPreferences("data",Context.MODE_PRIVATE).edit{
putString("name","ZLS")
putInt("age",18)
putBoolean("married",false)
}
简化ContentValues的用法
ContentValues主要是用于结合SQLiteDatabase的API存储和修改数据库中的数据,具体的基础用法如 下:
val values = ContentValues()
values.put("name", "Game of Thrones")
values.put("author", "George Martin")
values.put("pages", 720)
values.put("price", 20.85)
db.insert("Book", null, values)
下面介绍通过新建一个方法让其变得简单的用法:
首先新建⼀个ContentValues.kt文件,然后在里面定义一个cvOf()方法:
fun cvOf(vararg pairs: Pair<String, Any?>): ContentValues {
}
这个方法的作用是构建一个ContentValues对象。
首先,cvOf()方法接收了一个Pair参数,也就是使用A to B语法结构创建出来的参数类型,但是在参数前面加上了一个vararg关键字,它对应的就是Java中的可变参数列表,允许向这个方法传入0个、1个、2个甚至任意多个Pair类型的参数,这些参数都会被赋值到使用vararg声明的这一个变量上面,然后使用for-in循环可以将传入的所有参数遍历出来。
再来看声明的Pair类型。由于Pair是一种键值对的数据结构,因此需要通过泛型来指定它的键和值分别对应什么类型的数据。ContentValues的所有键都是字符串类型的,这里可以直接将Pair键的泛型指定成String。但ContentValues的值却可以有多种类型(字符串型、整型、浮点型,甚至是null),所以需要将Pair值的泛型指定成Any?。这是因为Any是Kotlin中所有类的共同基类,相当于Java中的Object,而Any?则表示允许传入空值。
fun cvOf(vararg pairs: Pair<String, Any?>): ContentValues {
val cv = ContentValues()
for (pair in pairs) {
val key = pair.first
val value = pair.second
when (value) {
is Int -> cv.put(key, value)
is Long -> cv.put(key, value)
is Short -> cv.put(key, value)
is Float -> cv.put(key, value)
is Double -> cv.put(key, value)
is Boolean -> cv.put(key, value)
is String -> cv.put(key, value)
is Byte -> cv.put(key, value)
is ByteArray -> cv.put(key, value)
null -> cv.putNull(key)
}
}
return cv
}
when语句进入Int条件分支后,这个条件下面的value会被自动转换成Int类型,而不再是Any?类型,这样就不需要像Java中那样再额外进行一次向下转型了, 这个功能在if语句中也同样适用。
有了这个cvOf()方法之后,使用ContentValues时就会变得更加简单了,比如向数据库中插入一条数据就可以这样写:
val values = cvOf("name" to "Game of Thrones", "author" to "George Martin", "pages" to 720, "price" to 20.85)
db.insert("Book", null, values)
此外,还可以借助apply函数进行二次优化
fun cvOf(vararg pairs: Pair<String, Any?>) = ContentValues().apply {
for (pair in pairs) {
val key = pair.first
val value = pair.second
when (value) {
is Int -> put(key, value)
is Long -> put(key, value)
is Short -> put(key, value)
is Float -> put(key, value)
is Double -> put(key, value)
is Boolean -> put(key, value)
is String -> put(key, value)
is Byte -> put(key, value)
is ByteArray -> put(key, value)
null -> putNull(key)
}
}
}
在上文提到的KTX库中也提供了一个具有同样功能的contentValuesOf()方法,用法如下:
val values = contentValuesOf("name" to "Game of Thrones", "author" to "George Martin", "pages" to 720, "price" to 20.85)
db.insert("Book", null, values)
平时在编写代码的时候,直接使用KTX提供的contentValuesOf()方法就可以了。










