Skip to content

UI 层生命周期安全收集

源:Android 响应式流收集指南

在 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()