博客中涉及的主题:
- 为什么选择Jetpack DataStore?
- SharedPreferences与DataStore首选项
- 实施Jetpack DataStore首选项
- 从SharedPreferences迁移到DataStore Preferences
首先,为什么要使用这个新的Jetpack DataStore?
为什么选择Jetpack DataStore?
根据官方文档:
- Jetpack DataStore是一种新的经过改进的数据存储解决方案,旨在替代SharedPreferences。
- 它建立在Kotlin Coroutines和Flow的基础上。
- 数据以异步,一致和事务的方式存储,克服了SharedPreferences的大多数缺点。
上述改进是巨大的。
我会告诉您一个原因,为什么我会从我的实际经验中推荐新的Jetpack DataStore。
我当时正在开发一个下载量超过2亿的Android应用程序,该应用程序在Google Play商店中的使用已超过7年。在很长的一段时间内,该应用程序经历了巨大的发展,发布了许多版本,并修复了许多错误。
因此,在某个时候,该应用程序开始获取ANR(应用程序无响应)。
ANR的原因:该应用程序正在UI线程上执行长时间运行的任务。(超过5秒)。
为什么这个ANR来了?
主要原因是我们的共享首选项文件太大了,因为我们一直在不断添加新的键值。应用程序在UI线程上打开后,我们正尝试访问特定键的值。但事实是,当您第一次访问SharedPreferences时,它将读取整个文件,并将数据带入内存。对于我们来说,这是在UI Thread上发生的。
这是一个I / O操作。这可能需要一些时间。对于我们来说更大的文件,它导致了ANR。
现在,让我们谈谈SharedPreferences与DataStore Preferences。
SharedPreferences与DataStore首选项
以下是SharedPreferences和DataStore首选项之间的区别:
- 两者都提供异步API。
- SharedPreferences提供了一个简单的Synchronous API,但是在UI线程上调用并不安全。DataStore首选项不鼓励这样做。
- 在DataStore首选项中保证一致性。
- DataStore首选项支持错误处理。
- 默认情况下,DataStore首选项支持Kotlin Coroutines Flow API。
这就是DataStore首选项是对SharedPreferences的改进解决方案的方式。
现在,让我们转到实现部分。
实施Jetpack DataStore首选项
在您的应用程序级别build.gradle中添加以下依赖项。
implementation "androidx.datastore:datastore-preferences:1.0.0-alpha01"
注意:确保使用最新版本以获得最稳定的版本。
现在,类似于SharedPreferences对象,我们需要创建DataStore Preferences的对象。
val dataStore: DataStore<Preferences> =
context.createDataStore(name = "mindorks-data-store-prefs")
然后,我们创建两个扩展功能以使用它们读取和写入数据。这只是为了方便。
fun <T> DataStore<Preferences>.getValueFlow(
key: Preferences.Key<T>,
defaultValue: T
): Flow<T> {
return this.data
.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences())
} else {
throw exception
}
}.map { preferences ->
preferences[key] ?: defaultValue
}
}
suspend fun <T> DataStore<Preferences>.setValue(key: Preferences.Key<T>, value: T) {
this.edit { preferences ->
preferences[key] = value
}
}
然后,我们如下创建首选项键:
companion object {
private val USERNAME = preferencesKey<String>("username")
}
现在,将值写入“ DataStore首选项”:
viewModelScope.launch {
dataStore.setValue(USERNAME, "Amit Shekhar")
}
现在,从“ DataStore首选项”中读取数据:
viewModelScope.launch {
dataStore.getValueFlow(USERNAME, "")
.collect { value ->
// use the value
}
}
在这里,我们可以通过catch
在流上使用运算符来处理错误。
viewModelScope.launch {
dataStore.getValueFlow(USERNAME, "")
.catch {
// handle error
}
.collect { value ->
// use the value
}
}
这就是我们可以在Android应用程序中轻松使用它的方式。
现在,让我们讨论一下从SharedPreferences到DataStore Preferences的迁移。
从SharedPreferences迁移到DataStore Preferences
当涉及迁移时,DataStore会为我们处理。我们只需要提供SharedPreferences的名称。例如,如果“ mindorks-prefs ”是SharedPreferences的名称,我们将必须执行以下操作:
val dataStore: DataStore<Preferences> =
context.createDataStore(
name = "mindorks-data-store-prefs",
migrations = listOf(SharedPreferencesMigration(context, "mindorks-prefs"))
)
当我们检查SharedPreferencesMigration
功能时:
fun SharedPreferencesMigration(
context: Context,
sharedPreferencesName: String,
keysToMigrate: Set<String>? = MIGRATE_ALL_KEYS,
deleteEmptyPreferences: Boolean = true
)
我们可以看到还有更多可用的选项,我们可以根据用例来使用它们。
从SharedPreferences迁移到DataStore Preferences的方法非常简单。
0 条评论