观察 Android Jetpack DataStore 值的变化

9

我是否遗漏了什么,或者无法在新的Android Jetpack首选项数据存储中附加侦听器?我认为使用Flow的整个重点是我们可以在Preference Datastore上调用flow.toLiveData()并观察值更改的变化。

以下是我如何从Datastore获取Flow。

 val taxRatePreferenceFlow: Flow<TaxRate> = dataStore.data
        .catch { exception ->
            if (exception is IOException){
                emit(emptyPreferences())
            } else {
                throw exception
            }
        }.map { preferences ->
            val name = preferences[PreferencesKeys.TAX_LABEL] ?: "Tax"
            val rate = preferences[PreferencesKeys.TAX_RATE] ?: Constants.DEFAULT_TAX_RATE.toFloat()
            val type = TaxType.valueOf(preferences[PreferencesKeys.TAX_TYPE] ?: TaxType.ON_ITEMS.name)
            TaxRate(name, rate, type)
        }

我希望在ViewModel中将Flow转换为LiveData,并监听直到观察者被移除。
totalAmountLiveData.addSource(taxRateFlow.asLiveData()){ taxtRate ->
            taxtRate?.let {
                updateTaxAmount(it)
            }
        }

然而,这个观察者只会发出保存的值,并不会在值更新时进行更新。退出并重新进入屏幕时,才能看到更新后的值。

以下是我如何更新DataStore中的每个值:

 suspend fun updateTaxLabel(newTaxLabel: String){
        dataStore.edit { preferences ->
            preferences[PreferencesKeys.TAX_LABEL] = newTaxLabel
        }
    }

我是否应该使用collect而不是map?如果是,请问有人能在这种情况下给我展示如何使用Flow collect的例子吗?


观察 totalAmountLiveData 是什么?updateTaxAmount() 函数是用来做什么的? - ianhanniballake
一个Fragment正在观察totalAmountLiveData,而updateTaxAmount调用了一个方法,该方法使用TaxRate的值进行一些计算。谢谢。 - Val Okafor
updateTaxAmount(..) 的返回类型是什么? - Achraf Amil
请查看此链接,希望对您有所帮助。https://dev59.com/Hb7pa4cB1Zd3GeqPtzer#65075272 - Royal Lachinov
1
@ValOkafor,你找到解决方案了吗? - guy.gc
1个回答

3

您可以直接将流作为LiveData观察,无需将其添加为另一个LiveData的源。

您的代码将会改变:

totalAmountLiveData.addSource(taxRateFlow.asLiveData()){ taxtRate ->
        taxtRate?.let {
            updateTaxAmount(it)
        }
    }

为了

taxRateFlow.asLiveData().observe(this */ lifeCycleOwner */) {
            updateTaxAmount(it)
}

在这种情况下,您可以直接查看数据存储并相应地执行功能。

这里遇到了问题。问题在于asLiveData()调用collect(),因此Flow被终止,您将无法获得进一步的更新... - Droidman
@Droidman,有没有办法观察首选项的变化? - KenIchi
@KenIchi,我还没有进一步调查这个问题,因为数据存储的迁移在优先级列表中排得很后面,所以我暂时无法提供任何更新,抱歉。 - Droidman
2
我已确认preferencesDataStore可以被订阅并实时更新,您可以观察它以获取进一步的更改。 查看此Gist:https://gist.github.com/KentVu/a65baf115adc0fb91a13d14bee7054f9 - KenIchi
1
@KenIchi,代码看起来是正确的,但问题出在asLiveData()上。Android文档提到,在Flow成功完成后,它将不会被重新收集(在asLiveData的情况下)。DataStore确实是为异步和即时更新而构建的。谢谢。 - Priyansh Kedia
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接