Androidx首选项库与DataStore首选项

我之前按照 Google 在文档中的建议,用新的 DataStore 替换了我的应用程序中的 SharedPreferences,以获得一些明显的好处。然后是添加设置屏幕的时候了,我找到了首选项库。当我看到库默认使用 SharedPreferences 而没有切换到 DataStore 的选项时,困惑就来了。您可以使用setPreferenceDataStore提供自定义存储实现,但 DataStore 没有实现 PreferenceDataStore 接口,由开发人员决定。是的,这个命名也非常令人困惑。当我发现没有关于将 DataStore 与 Preferences Library 一起使用的文章或问题时,我变得更加困惑,所以我觉得我错过了一些东西。人们是否同时使用这两种存储解决方案?还是其中之一?如果我要在 DataStore 中实现 PreferenceDataStore,有什么我应该注意的问题/陷阱吗?

回答

对于任何阅读问题并思考setPreferenceDataStore-solution 的人。使用 DataStore 而不是 SharedPreferences 实现您自己的 PreferencesDataStore 一目了然。

class SettingsDataStore(private val dataStore: DataStore<Preferences>): PreferenceDataStore() {

    override fun putString(key: String, value: String?) {
        CoroutineScope(Dispatchers.IO).launch {
            dataStore.edit {  it[stringPreferencesKey(key)] = value!! }
        }
    }

    override fun getString(key: String, defValue: String?): String {
        return runBlocking { dataStore.data.map { it[stringPreferencesKey(key)] ?: defValue!! }.first() }
    }

    ...
}

然后在您的片段中设置数据存储

@AndroidEntryPoint
class AppSettingsFragment : PreferenceFragmentCompat() {

    @Inject
    lateinit var dataStore: DataStore<Preferences>

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        preferenceManager.preferenceDataStore = SettingsDataStore(dataStore)
        setPreferencesFromResource(R.xml.app_preferences, rootKey)
    }
}

但是这个解决方案存在一些问题。根据文档 runBlockingfirst()同步读取值是首选方式,但应谨慎使用。

确保preferenceDataStore在调用之前进行设置setPreferencesFromResource以避免加载问题,其中默认实现 (sharedPreferences) 将用于初始加载。

几周前,在我最初尝试实现 PreferenceDataStore 时,我遇到了类型long键的问题。我的设置屏幕正确地显示和保存了一个数值,EditTextPreference但流没有为这些键发出任何值。EditTextPreference将数字保存为字符串可能会出现问题,因为在 xml 中设置 inputType 似乎没有效果(至少在输入键盘上没有效果)。虽然将数字保存为字符串可能有效,但这也需要将数字作为字符串读取。因此,您失去了原始类型的类型安全性。

也许对设置和数据存储库进行一两次更新,可能会有针对这种情况的官方工作解决方案。


以上是Androidx首选项库与DataStore首选项的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>