对支持哪些 DataStore 方法感到困惑

问题描述 投票:0回答:1

TLDR:我今天大部分时间都在与

DataStore
作斗争,更具体地说,为什么大多数挂起方法似乎永远挂起,只有
map {}.first
可以帮助我获取
Preferences
对象。


背景

我正在编写一个小型 Android 应用程序,非常轻量地使用本地存储:

  1. 我需要在应用程序启动时从本地存储读取所有设置(但不需要阻止)。
  2. 当用户与应用程序交互时,更新本地存储。无需再阅读了。

示例

最终起作用的是:

val preferences =
            context.transliterationStatesDataStore.data.firstOrNull() ?: return
val preferences =
            context.dataStore.data.map { preferences -> preferences }
                .first()

我之前尝试过:

val preferences =
            context.dataStore.data.map { preferences -> preferences }
                .lastOrNull() ?: return
val preferences =
            context.dataStore.data.lastOrNull() ?: return
Log.d("debug", context.dataStore.data.count().toString())

混乱

我很困惑为什么:

  1. .count()
    不起作用(永远暂停)
  2. .lastOrNull()
    不起作用(永远暂停)
  3. 当我想要的是磁盘中 Preferenceslatest 版本时,读取流的
    first
    值感觉不对。

有一个相关问题here,但除了作者提供的更多数据点之外,没有收到任何答案。

android kotlin sharedpreferences kotlin-coroutines
1个回答
0
投票
  1. .count()
    不起作用(永远暂停)

只要 Flow 不断发出新值(

DataStore.data
将会发出新值,或者除非
Flow
被取消),该值将
永远不会
被解析 - 这是
.count()
方法的实现
:

public suspend fun <T> Flow<T>.count(): Int  {
    var i = 0
    collect {
        ++i
    }

    return i
}
  1. .lastOrNull()
    不起作用(永远暂停)

同样适用于

.lastOrNull()
,它将挂起直到发出最后一个值,这永远不会发生(源代码):

public suspend fun <T> Flow<T>.lastOrNull(): T? {
    var result: T? = null
    collect {
        result = it
    }
    return result
}
  1. 当我想要的是磁盘上最新版本的首选项时,读取流的第一个值感觉不对。

这就是从

Flow
收集的目的,这样您将始终获得最新的值:

yourPreferenceDataStore.data.collect {
  // Get latest updates here
  println(it)
}

// Or if you want to get a specific data from the DataStore
val whateverData = yourPreferenceDataStore.data.map { it.whatever }

如果您需要在 Compose 中使用它,您可以使用

collectAsState
/
collectAsStateWithLifecycle
将其收集为 Compose
State
以在您的可组合项中使用:

@Composable
fun MyScreen() {
  val yourData by dataStore.data.collectAsStateWithLifecycle(initialValue = /* initial value */)
}
© www.soinside.com 2019 - 2024. All rights reserved.