繁体   English   中英

如何在视图模型中从 DataStore 首选项中获取值,如 Flow

[英]How to get a value from DataStore preferences, as Flow, within viewmodel

我有一种情况可以通过 SharedPreferences 解决。 但现在我正在迁移到 kotlin 和 DataStore。

我遇到了这个问题。

我有一个字符串值存储在共享首选项中,以及其他键值对。 此字符串是 URL,用于 Retrofit 调用的 baseUrl 参数中。

我的问题是,当我在 ViewModel 中运行 Fragment 时,检索值的正确方法是什么。

这是我的代码的一部分:

@Singleton
class PreferencesManager @Inject constructor(
    @ApplicationContext context: Context,
    anioDao: AnioDao
) {

   val baseUrlFlow = dataStore.data
        .catch { exception ->
            if (exception is IOException) {
                Log.e(TAG, "Error reading preferences: ", exception)
                emit(emptyPreferences())
            } else {
                throw exception
            }
        }
        .map {
            it[PreferencesKeys.BASER_URL] ?: "http://192.168.2.109:1337"
        }

}

然后在 ViewModel class

class EnsayosViewModel @ViewModelInject constructor(
    private val ensayoRepository: EnsayoRepository,
    private val anioRepository: AnioRepository,
    private val localidadRepository: LocalidadRepository,
    private val epocaRepository: EpocaRepository,
    private val preferencesManager: PreferencesManager,
    private val agrotrackerApi: AgrotrackerApi,
    @Assisted private val state: SavedStateHandle

) :
    ViewModel() {

...

//Base Url
val baseUrlFlow = preferencesManager.baseUrlFlow
private val _baseUrl = MutableLiveData<String>()
private fun getBaseUrl() {

    viewModelScope.launch {
        baseUrlFlow.flowOn(Dispatchers.IO).collect{
            _baseUrl.value = it
        }
    }
}

  ...

fun fetchEsayosFromAT() {

 //This is where I want to get value of the base_url key.

}

但这似乎很复杂,对于一个简单的任务......

我错过了什么? 我真的迷路了。

此致

获取共享首选项数据的一种方法是将 Flow 转换为 LiveData。 它工作正常,但很可能会被 StateFlow/SharedFlow 取代,作为首选方法。

  1. 在返回 Flow 的 Preference 存储库中创建一个方法

    override fun getBaseUrlPreferencesFlow(): Flow<String> = context.dataStore.data.catch { exception -> if (exception is IOException) { Log.e(TAG, "Error reading preferences: ", exception) emit(emptyPreferences()) } else { throw exception } }.map { pref -> it[PreferencesKeys.BASER_URL]?: "http://192.168.2.109:1337" }
  2. 在您的 ViewModel 中初始化 LiveData,如下所示(您可以从 ViewModel 或 Fragment 访问它)

     val baseUrlLiveData: LiveData<String> = yourInjectedRepository.getBaseUrlPreferencesFlow().asLiveData()
  3. (可选)在 ViewModel - 添加辅助方法来处理基础 url

     private fun processUrl(): String { viewModelScope.launch { // base url http://192.168.2.109:1337 val url = baseUrlLiveData.value } }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM