前言
DataStore 是用来取代 SharedPreferences
的一种简易数据存储的解决方案。
既然是方案,也就是说 DataStore 并不是具体的代码实现,目前其具体实现有两种方式:
- Preferences DataStore
- Proto DataStore
下面我们来看看如何使用 Preferences DataStore
。
创建
首先我们得添加下依赖:
implementation "androidx.datastore:datastore-preferences:1.0.0"
复制代码
然后创建 DataStore:
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "number")
复制代码
存储数据
在以往我们使用 SharedPreferences
的时候,我们都是使用 <Key, Value> 的形式进行填写的,但是 DataStore 与 SharedPreferences
不同的是,DataStore 并不是以 String 作为 key,而是以 Preferences.Key
作为 Key,不同的数据类型需要不同写法:
- Int -> intPreferencesKey(name)
- Double -> doublePreferencesKey(name)
- String -> stringPreferencesKey(name)
- Boolean -> booleanPreferencesKey(name)
- Float -> floatPreferencesKey(name)
- Long -> longPreferencesKey(name)
- Set -> stringSetPreferencesKey(name)
这里我以存储 int 类型作为示例:
val EXAMPLE_COUNTER = intPreferencesKey("example_counter") // 创建 key
dataStore.edit { settings ->
val currentCounterValue = settings[EXAMPLE_COUNTER] ?: 0
settings[EXAMPLE_COUNTER] = currentCounterValue + 1
}
复制代码
大概意思其实就是把值读取出来,然后 +1 在放回去。
读取数据
val EXAMPLE_COUNTER = intPreferencesKey("example_counter") // 创建 key
val exampleCounterFlow: Flow<Int> = dataStore.data
.map { preferences ->
preferences[EXAMPLE_COUNTER] ?: 0
}
复制代码
要注意,exampleCounterFlow 是一个 Flow,是一个冷流,map 只是一个数据转换,所以,想要真正获取数据还需要调用 collect:
dataStore.data
.map { preferences ->
preferences[EXAMPLE_COUNTER] ?: 0
}.collect {
println("EXAMPLE_COUNTER 的值:$it")
}
复制代码
清除全部数据
dataStore.edit {
it.clear()
}
复制代码
SharedPreferences 兼容
Preferences DataStore
还提供一种方式,将 SharedPreferences
里面的数据迁移到 Preferences DataStore
中。
首先,我们先来回顾下 SharedPreferences
。
写入数据:
getSharedPreferences("old_data", MODE_PRIVATE).edit().apply {
putString("name", "不近视的猫")
apply()
}
复制代码
文件生成:
文件内容:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="name">不近视的猫</string>
</map>
复制代码
下面就是通过 SharedPreferencesMigration
进行 SharedPreferences
的迁移了:
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "new_data",
produceMigrations = { context ->
listOf(SharedPreferencesMigration(context, "old_data"))
})
复制代码
当然,直接这样声明是不会进行运行的,需要稍微使用到 dataStore:
GlobalScope.launch {
dataStore.edit { }
}
复制代码
然后我们就能看到 old_data.xml
文件被删除了,而被取代的是 /data/data/com.bjsdm.testkotlin/files/datastore/new_data.preferences_pb
:
- 我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。