如何安全地(生命周期感知).collectAsState() StateFlow?

Dis*_*Dev 18 android kotlin kotlin-coroutines android-jetpack-compose kotlin-flow

我正在尝试遵循官方指南,根据以下文章,使用 Compose 从 LiveData 迁移到 Flow/StateFlow:

\n

从 Android UI 收集流量的更安全方法

\n

从 LiveData 迁移到 Kotlin\xe2\x80\x99s 流程

\n

我尝试遵循第一篇文章末尾处的 Jetpack Compose 中的安全流集合中的建议。

\n
\n

在 Compose 中,副作用必须在受控环境中执行。\n 为此,请使用 LaunchedEffect 创建一个遵循可组合\xe2\x80\x99s 生命周期的协程。在其块中,如果您需要在主机生命周期处于某种状态时重新启动代码块,则可以调用\nsuspend Lifecycle.repeatOnLifecycle。

\n
\n

我设法以这种方式使用.flowWithLifecycle()来确保当应用程序转到后台时流不会发出:

\n
@Composable\nfun MyScreen() {\n\n    val lifecycleOwner = LocalLifecycleOwner.current\n\n    val someState = remember(viewModel.someFlow, lifecycleOwner) {\n        viewModel.someFlow\n            .flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED)\n            .stateIn(\n                scope = viewModel.viewModelScope,\n                started = SharingStarted.WhileSubscribed(5000),\n                initialValue = null\n            )\n    }.collectAsState()\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我发现这非常“样板”——一定有更好的东西。我想在 ViewModel 中使用 StateFlow,而不是在 @Composable 中转换为 StateFLow 的 Flow,并使用.repeatOnLifeCycle(),这样我就可以使用多个.collectAsState()来减少样板文件。

\n

当我尝试在协程(LaunchedEffect)中使用 .collectAsState() 时,我显然收到一个关于必须从 @Composable 函数的上下文中调用 .collectAsState() 的错误。

\n

如何实现与 .collectAsState() 类似的功能,但在 .repeatOnLifecycle() 内部。我是否必须在 StateFlow 上使用 .collect() 然后用 State 包装该值?难道没有比这更少样板的东西了吗?

\n

Thi*_*uza 27

“androidx.lifecycle:lifecycle-runtime-compose:2.6.0-rc01”中,您可以使用collectAsStateWithLifecycle()扩展函数从flow/stateflow中收集,并以生命周期感知的方式将其最新值表示为Compose State。

import androidx.lifecycle.compose.collectAsStateWithLifecycle

@Composable
fun MyScreen() {
    val state by viewModel.state.collectAsStateWithLifecycle()
}
Run Code Online (Sandbox Code Playgroud)

来源:Android 生命周期版本