博客中涉及的主题:

  • 为什么选择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
分类: 未分类

bayshier

愿世间每个美好的灵魂都能被温柔以待

0 条评论

发表评论

邮箱地址不会被公开。 必填项已用*标注