【发布时间】:2022-01-09 21:32:20
【问题描述】:
根据这些文章,我正在尝试按照官方指南使用 Compose 从 LiveData 迁移到 Flow/StateFlow:
A safer way to collect flows from Android UIs
Migrating from LiveData to Kotlin’s Flow
我正在尝试遵循第一篇文章中的建议,在接近结尾的 Jetpack Compose 中的安全流程集合部分。
在 Compose 中,副作用必须以受控的方式执行 环境。为此,使用 LaunchedEffect 创建一个协程 遵循可组合的生命周期。在其块中,您可以调用 如果需要重新启动 Lifecycle.repeatOnLifecycle,请暂停 Lifecycle.repeatOnLifecycle 主机生命周期处于特定状态时的代码块。
我已经设法以这种方式使用.flowWithLifecycle() 来确保当应用程序进入后台时流不会发出:
@Composable
fun MyScreen() {
val lifecycleOwner = LocalLifecycleOwner.current
val someState = remember(viewModel.someFlow, lifecycleOwner) {
viewModel.someFlow
.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED)
.stateIn(
scope = viewModel.viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = null
)
}.collectAsState()
}
我觉得这很“样板”——一定有更好的东西。我想在 ViewModel 中使用 StateFlow,而不是在 @Composable 中转换为 StateFLow 的 Flow,并使用 .repeatOnLifeCycle(),因此我可以使用多个 .collectAsState() 并减少样板。
当我尝试在协程 (LaunchedEffect) 中使用 .collectAsState() 时,我显然会收到关于必须从 @Composable 函数的上下文中调用 .collectAsState() 的错误。
如何实现与 .collectAsState() 类似的功能,但在 .repeatOnLifecycle() 内部。我是否必须在 StateFlow 上使用 .collect() 然后用 State 包装值?没有比这更少的样板吗?
【问题讨论】:
标签: android kotlin android-jetpack-compose kotlin-coroutines kotlin-flow