Android jetpack DataStore 1.0.0-rc02最新版从SharedPreferences迁移到Preferences DataStore
前言
一直听说新的持久化存储库DataStore完爆Android一直在使用的SharedPreferences,但是由于工作忙碌,加上DataStore一直没有从alpha版本跳出,所以没有认真去了解和学习DataStore,现在刚好有空余时间,就开始深入学习一下。
对我而言,DataStore的新特性几乎就是kotlin体系带来的优势,对于已经用了一年kotlin的开发者来说,创建DataStore以及读写数据,几乎手到擒来,看一下就明白了,但是一参考官方的Codelab,写一个DEMO,我就懵了,官方的开发者指南还是按照alpha6版的API来写的,最新的rc02的版本却完全没有context.createDataStore() 这个API。行吧alpha就是个alpha。
进过一番查询,终于在官方的说明文档中找到了,新的使用方法: DataStore
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
好家伙,看起来简洁了些,但是如何从SharedPreferences迁移到Preferences DataStore呢? 行吧,整个百度都没搜出来…
迁移
public fun preferencesDataStore(
name: String,
corruptionHandler: ReplaceFileCorruptionHandler<Preferences>? = null,
produceMigrations: (Context) -> List<DataMigration<Preferences>> = { listOf() },
scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
): ReadOnlyProperty<Context, DataStore<Preferences>> {
return PreferenceDataStoreSingletonDelegate(name, corruptionHandler, produceMigrations, scope)
}
在preferencesDataStore方法中有一个参数是produceMigrations,这个看起来就是迁移的方法了,需要返回一个List,不难看出,和alpha6版的参数migrations如出一辙,直接抄过来即可
val Context.dataStore: DataStore<Preferences> by preferencesDataStore("new_datastore", produceMigrations = { con ->
listOf(SharedPreferencesMigration(con, "old_spf"))
})
测试
为了验证我的思路,写一个demo进行验证;
- 首先,先把旧的SharedPreferences存储类给出:
class SpfUtils constructor(context: Context, spName: String) {
private val mSpf = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
companion object {
@Volatile
private var INSTANCE: SpfUtils? = null
@JvmStatic
fun instant(context: Context, spName: String) : SpfUtils =
INSTANCE ?: synchronized(this) {
INSTANCE ?: SpfUtils(context, spName).also {
INSTANCE = it
}
}
}
fun getSpf() : SharedPreferences {
return mSpf
}
}
const val SP_CONFIG = "old_spf"
fun Context.getSpf(spName: String = SP_CONFIG) = SpfUtils.instant(this, spName).getSpf()
const val SPF_SAVE_NAME = "save_name"
fun Context.getSpfSaveName(): String =
getSpf().getString(SPF_SAVE_NAME, null)?: ""
fun Context.setSpfSaveName(value: String) {
getSpf().edit().putString(SPF_SAVE_NAME, value).apply()
}
val Context.dataStore: DataStore<Preferences> by preferencesDataStore("new_datastore", produceMigrations = { con ->
listOf(SharedPreferencesMigration(con, SP_CONFIG))
})
suspend fun Context.readSaveName(): String {
return dataStore.data.map {
it[stringPreferencesKey(SPF_SAVE_NAME)]?: "NULL"
}.first()
}
suspend fun Context.writeSaveName(value: String) {
dataStore.edit {
it[stringPreferencesKey(SPF_SAVE_NAME)] = value
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSpfSaveName("你好,SPF")
println("SPF 打印:${getSpfSaveName()}")
CoroutineScope(Dispatchers.IO).launch {
println("dataStore 打印:${readSaveName()}")
writeSaveName("你好,dataStore")
println("dataStore 打印:${readSaveName()}")
}
}
}
I/System.out: SPF 打印:你好,SPF
I/System.out: dataStore 打印:你好,SPF
I/System.out: dataStore 打印:你好,dataStore
完事
|