android - 使用 repeatOnLifeCycle 从 UI 中的 Flow 收集

标签 android kotlin coroutine kotlin-flow

我开始用 Flow 替换 LiveData 因为它更灵活。但后来我发现您需要编写大量样板代码才能从 UI 中的 Flow 观察。

StateFlow documentation , 它说

LiveData.observe() automatically unregisters the consumer when the view goes to the STOPPED state, whereas collecting from a StateFlow or any other flow does not stop collecting automatically. To achieve the same behavior,you need to collect the flow from a Lifecycle.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/

相关文章:

java - SingleValueEvent 显示为空

android - IONIC 5 Cordova 插件可以构建,但在运行 android 时无法工作。它仅在 -livereload 中工作

java - 我们如何监听 Android 中的位置权限更改(不触发权限请求)?

kotlin - 在 Kotlin 中创建异步函数

lambda - RXKotlin Lambda 理解

c# - Unity中协程的异常处理

android - 在android中像gmail一样显示弹出窗口

android - 如何在 Kotlin 中制作多个构造函数?

multithreading - Lua协程还有什么用?为什么此代码无法按我预期的那样工作?

动画曲线评估