我开始用 Flow
替换 LiveData
因为它更灵活。但后来我发现您需要编写大量样板代码才能从 UI 中的 Flow
观察。
在StateFlow documentation , 它说
LiveData.observe()
automatically unregisters the consumer when the view goes to theSTOPPED
state, whereas collecting from aStateFlow
or any other flow does not stop collecting automatically. To achieve the same behavior,you need to collect the flow from aLifecycle.repeatOnLifecycle
block.
article 中也提到了它作者 Manuel Vivo,使用从 lifecycleScope.launchWhenX
收集是危险的,不应在 UI 中使用,因为生产者流不会停止发射。
他推荐我们使用
// Listen to multiple flows
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
// As collect is a suspend function, if you want to collect
// multiple flows in parallel, you need to do so in
// different coroutines
launch {
flow1.collect { /* Do something */ }
}
launch {
flow2.collect { /* Do something */ }
}
}
}
样板代码量太多。不可能像 LiveData
那样在两行中完成吗?
viewModel.movieData.observe(viewLifecycleOwner) {
...
}
为什么在 UI 中从 Flow
收集如此复杂?使用 asLiveData()
将 Flow 转换为 LiveData 是否可取?
最佳答案
您可以构建扩展以减少样板文件
inline fun <T> Flow<T>.collectIn(
owner: LifecycleOwner,
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
crossinline action: suspend CoroutineScope.(T) -> Unit
) = owner.addRepeatingJob(minActiveState, coroutineContext) {
collect {
action(it)
}
}
这使得收集流类似于 LiveData 作为
flow.collectIn(viewLifecycleOwner){ /* do stuff */ }
关于android - 使用 repeatOnLifeCycle 从 UI 中的 Flow 收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68279765/