我正在尝试使用以下代码:
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 构造函数中的字段。(这甚至可能在“结构化并发”的范围内吗?)