刚好新项目中有用好DataStore,整理了下快速上手方法,背景如下
本文是基于最新的1.0.0-alpha08
版本,文章有现成的分装好的方法,可以直接拿来用,使用前,先介绍下DataStore的特性
1、文件的命名,后缀必须用preferences_pb,可以看下内部的代码
check(file.extension == PreferencesSerializer.fileExtension) {
"File extension for file: $file does not match required extension for" +
" Preferences file: ${PreferencesSerializer.fileExtension}"
}
2、存储的文件路径,建议使用内部存储,避免涉及权限申请,类似下面这个
3、类似之前的SP,如果是多个表格,需要使用多个实例,这里的例子,就一个全局的实例
private const val DEFAULT_DATA_PATH = "DefaultSpDataPath.preferences_pb"
/**
* 默认的实例
*/
private val defaultDataStore by lazy {
PreferenceDataStoreFactory.create {
val parentFile =
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
BaseApplication.getApplication().dataDir
} else {
BaseApplication.getApplication().filesDir
}
File(parentFile.absolutePath, DEFAULT_DATA_PATH)
}
}
如果要多个实例,就再调用PreferenceDataStoreFactory.create来创建,然后传入不同的file地址,实例要跟地址一一匹配
/**
* 保存SP数据的工具类,所有的sp的操作,要统一调用这个方法
*/
object SpUtils {
/**
* 读取sp的值
*/
suspend fun <T> readValue(key: String, default: T): T {
val value = defaultDataStore.data.map { setting ->
when (default) {
is String -> {
setting[stringPreferencesKey(key)] ?: default
}
is Int -> {
setting[intPreferencesKey(key)] ?: default
}
is Long -> {
setting[longPreferencesKey(key)] ?: default
}
is Boolean -> {
setting[booleanPreferencesKey(key)] ?: default
}
is Float -> {
setting[floatPreferencesKey(key)] ?: default
}
is Double -> {
setting[doublePreferencesKey(key)] ?: default
}
else -> {
throw IllegalArgumentException("Illegal default type $default")
}
}
}
return value.first() as T
}
这里默认值使用了泛型,一是为了确定返回的类型;二是DataStore返回的结果是可空的,必须有默认值相匹配
/**
* 保存sp的值
*/
suspend fun <T> saveValue(key: String, value: T) {
defaultDataStore.edit { setting ->
when (value) {
is String -> {
setting[stringPreferencesKey(key)] = value
}
is Int -> {
setting[intPreferencesKey(key)] = value
}
is Long -> {
setting[longPreferencesKey(key)] = value
}
is Boolean -> {
setting[booleanPreferencesKey(key)] = value
}
is Float -> {
setting[floatPreferencesKey(key)] = value
}
is Double -> {
setting[doublePreferencesKey(key)] = value
}
}
}
}
val result runBlocking {
androidId = SpUtils.readValue("androidId", "")
if (TextUtils.isEmpty(androidId)) {
androidId = UUID.randomUUID().toString()
SpUtils.saveValue("androidId", androidId)
}
androidId
}
接下来,有空的话,就继续介绍DataStore内部实现,待续...