UI 层生命周期安全收集
在 Android 中,Activity/Fragment 可能会进入后台(STOPPED)。此时如果后台的 Flow 继续活跃发射数据,会造成严重的资源浪费甚至 Crash。
历史包袱:launchWhenXxx
已废弃 (Deprecated)。 launchWhenStarted 不会取消上游流,只会挂起收集。这意味着上游的生产者(如位置更新)可能仍在后台运行。
现代方案 A:repeatOnLifecycle
这是官方推荐的标准做法。 机制: 当生命周期低于指定状态(如 STOPPED)时,取消协程。当生命周期恢复(如 STARTED)时,重新启动协程。
kotlin
lifecycleScope.launch {
// ⭐️ 核心:在 STARTED 状态下反复执行
repeatOnLifecycle(Lifecycle.State.STARTED) {
// 当 UI 不可见时,这里的收集会被取消,从而停止上游流
viewModel.uiState.collect { ... }
}
}现代方案 B:flowWithLifecycle (流式)
如果你只有一个流需要收集,且不喜欢嵌套层级,可以用操作符形式。
kotlin
viewModel.uiState
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
.onEach { ... }
.launchIn(lifecycleScope)Jetpack Compose 专属
在 Compose 中,请务必使用 collectAsStateWithLifecycle。
kotlin
// 需要依赖: androidx.lifecycle:lifecycle-runtime-compose
val uiState by viewModel.uiState.collectAsStateWithLifecycle()