1. LiveData与Flow基础概念:生命周期感知、冷流热流区别、观察者模式

观察任务进度的本质是数据变化→观察者接收通知。Android 开发中,LiveData 和 Flow 是两种主流通用观察者机制,但设计目标与使用场景差异显著。本章从观察者模式出发,拆解生命周期感知与冷流/热流两大核心区别,为后续任务进度观察实现打下理论基础。

1.1 观察者模式——两者共同的根

无论是 LiveData 还是 Flow,底层都遵循观察者模式:一个被观察对象(数据源)维护一组依赖者(观察者),当数据变更时自动通知所有观察者。

特性LiveData 观察者Flow 观察者
订阅方式observe(LifecycleOwner, Observer).collect { } / .launchIn(scope)
通知时机主线程,自动协程调度器控制
取消订阅自动(生命周期绑定)手动或通过协程取消
比较: LiveData 专为 Android UI 层设计,自动处理生命周期;Flow 是 Kotlin 协程原语,更灵活,可用于非 UI 层。

1.2 LiveData:生命周期感知的观察者

LiveData 的核心价值在于自动感知 Activity/Fragment 生命周期,避免内存泄漏和空指针。当 LifecycleOwner 处于 STARTED 状态时订阅才会生效,在 DESTROYED 状态自动移除观察者。

// LiveData 基本使用 – ViewModel 层
class ProgressViewModel : ViewModel() {
    private val _progress = MutableLiveData<Int>(0)
    val progress: LiveData<Int> get() = _progress

    fun startTask() {
        viewModelScope.launch {
            for (i in 0..100 step 10) {
                delay(500)
                _progress.postValue(i)   // 主线程安全更新
            }
        }
    }
}

// Activity 层 – 自动感知生命周期
viewModel.progress.observe(this) { value ->
    progressBar.progress = value
}
常见错误: 在非 UI 线程调用 setValue() 会崩溃,必须使用 postValue()。若多次快速 postValue,只有最后一个值被传递,中间值可能丢失。

1.3 Flow:冷流与热流的分野

Flow 遵循冷流设计——每次订阅都重新执行上游生产者代码。与之相对,StateFlow 和 SharedFlow 是热流——数据独立于订阅者存在,多个订阅者共享同一数据流。

对比维度冷流(Flow)热流(StateFlow / SharedFlow)
生产者启动时机每次 collect 时重新启动生产者独立启动,订阅者不影响
数据缓存无,仅当前发射StateFlow 缓存最新值,SharedFlow 可配置 replay
生命周期感知需配合 repeatOnLifecycle同 Flow,但 StateFlow 常用于 UI 层
典型场景网络请求、数据库查询UI 状态管理、事件总线
// 冷流 Flow – 每次 collect 执行网络请求
fun fetchProgress(): Flow<Int> = flow {
    emit(0)
    delay(500)
    emit(50)
    delay(500)
    emit(100)
}.flowOn(Dispatchers.IO)   // 指定生产协程

// collect 时才开始执行
scope.launch {
    fetchProgress().collect { progress ->
        updateUI(progress)
    }
}

// 热流 StateFlow – 一直持有最新状态
private val _uiState = MutableStateFlow<Int>(0)
val uiState: StateFlow<Int> get() = _uiState

// 更新状态
_uiState.value = newProgress

// 任意订阅者立即拿到最新值
scope.launch {
    uiState.collect { progress ->
        // 自动接收新值和当前值
    }
}
工程建议: 在 UI 层观察任务进度首选 StateFlow + repeatOnLifecycle,既享受生命周期安全,又避免 LiveData 限制(如无法使用协程、无法区分数据是否“已消耗”)。

1.4 核心概念关系图

下图从观察者模式出发,梳理 LiveData 与 Flow 家族的关系,突出生命周期感知与冷/热流差异。

LiveData与Flow核心概念结构图 观察者模式 LiveData 生命周期感知(自动订阅/取消) 仅主线程通知 Flow 冷流(普通 Flow) 热流(StateFlow) 共同基础:观察者模式 关键区别:LiveData 自动处理生命周期 Flow 需手动配合 repeatOnLifecycle

1.5 调试与性能提示

  • 调试 LiveData: 在 observe 回调中加入日志,注意 postValue 的背压丢失问题;使用 observeForever 需手动 removeObserver。
  • 调试 Flow: 使用 .catch { } 处理异常,.onEach { } 添加日志,避免在收集时 block 过久。
  • 性能对比: LiveData 仅用于 UI 层时开销极低;Flow 在非阻塞协程场景下线程切换更精细,适合复杂数据流。