gpt4 book ai didi

android - 试图将 SavedStateHandle.getLiveData() 公开为 MutableStateFlow,但 UI 线程卡住

转载 作者:行者123 更新时间:2023-12-03 18:59:53 26 4
gpt4 key购买 nike

我正在尝试使用以下代码:

suspend fun <T> SavedStateHandle.getStateFlow(
key: String,
initialValue: T? = get(key)
): MutableStateFlow<T?> = this.let { handle ->
withContext(Dispatchers.Main.immediate) {
val liveData = handle.getLiveData<T?>(key, initialValue).also { liveData ->
if (liveData.value === initialValue) {
liveData.value = initialValue
}
}

val mutableStateFlow = MutableStateFlow(liveData.value)

val observer: Observer<T?> = Observer { value ->
if (value != mutableStateFlow.value) {
mutableStateFlow.value = value
}
}

liveData.observeForever(observer)

mutableStateFlow.also { flow ->
flow.onCompletion {
withContext(Dispatchers.Main.immediate) {
liveData.removeObserver(observer)
}
}.onEach { value ->
withContext(Dispatchers.Main.immediate) {
if (liveData.value != value) {
liveData.value = value
}
}
}.collect()
}
}
}
我正在尝试像这样使用它:
    // in a Jetpack ViewModel
var currentUserId: MutableStateFlow<String?>
private set

init {
runBlocking(viewModelScope.coroutineContext) {
currentUserId = state.getStateFlow("currentUserId", sessionManager.chatUserFlow.value?.uid)
// <--- this line is never reached
}
}
UI 线程卡住。我有一种感觉是因为 collect()因为我正在尝试创建一个由封闭的协程上下文管理的内部订阅,但我还需要将此 StateFlow 作为一个字段。还有值的交叉写入(如果其中一个发生更改,如果它是新值,则更新另一个)。
总的来说,这个问题似乎在 collect() 上。正在暂停,因为在 getStateFlow() 之后我从未真正到达该行.
有谁知道创建流的“内部订阅”的好方法,而不会最终卡住周围的线程? runBlocking {需要,以便我可以将值同步分配给 ViewModel 构造函数中的字段。 (这甚至可能在“结构化并发”的范围内吗?)

最佳答案

编辑:

// For more details, check: https://gist.github.com/marcellogalhardo/2a1ec56b7d00ba9af1ec9fd3583d53dc
fun <T> SavedStateHandle.getStateFlow(
scope: CoroutineScope,
key: String,
initialValue: T
): MutableStateFlow<T> {
val liveData = getLiveData(key, initialValue)
val stateFlow = MutableStateFlow(initialValue)

val observer = Observer<T> { value ->
if (value != stateFlow.value) {
stateFlow.value = value
}
}
liveData.observeForever(observer)

stateFlow.onCompletion {
withContext(Dispatchers.Main.immediate) {
liveData.removeObserver(observer)
}
}.onEach { value ->
withContext(Dispatchers.Main.immediate) {
if (liveData.value != value) {
liveData.value = value
}
}
}.launchIn(scope)

return stateFlow
}

原文:
您可以搭载 SavedStateHandle 中的内置通知系统,以便
val state = savedStateHandle.getLiveData<State>(Key).asFlow().shareIn(viewModelScope, SharingStarted.Lazily)

...
savedStateHandle.set(Key, "someState")
mutator 不是通过 MutableLiveData 的方法发生的。 ,但通过 SavedStateHandle这将在外部更新 LiveData(以及因此流)。

关于android - 试图将 SavedStateHandle.getLiveData() 公开为 MutableStateFlow,但 UI 线程卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65120398/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com