TLDR:我今天大部分时间都在与
DataStore
作斗争,更具体地说,为什么大多数挂起方法似乎永远挂起,只有 map {}.first
可以帮助我获取 Preferences
对象。
我正在编写一个小型 Android 应用程序,非常轻量地使用本地存储:
最终起作用的是:
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())
我很困惑为什么:
.count()
不起作用(永远暂停).lastOrNull()
不起作用(永远暂停)Preferences
的 latest 版本时,读取流的 first值感觉不对。
有一个相关问题here,但除了作者提供的更多数据点之外,没有收到任何答案。
不起作用(永远暂停).count()
只要 Flow
不断发出新值(
DataStore.data
将会发出新值,或者除非 Flow
被取消),该值将永远不会被解析 - 这是
.count()
方法的实现 :
public suspend fun <T> Flow<T>.count(): Int {
var i = 0
collect {
++i
}
return i
}
不起作用(永远暂停).lastOrNull()
同样适用于
.lastOrNull()
,它将挂起直到发出最后一个值,这永远不会发生(源代码):
public suspend fun <T> Flow<T>.lastOrNull(): T? {
var result: T? = null
collect {
result = it
}
return result
}
- 当我想要的是磁盘上最新版本的首选项时,读取流的第一个值感觉不对。
这就是从
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 */)
}