LiveData 现状回顾
核心原理:生命周期感知的观察者模式
LiveData 是 Android 架构组件中一个可观察的数据持有类,核心设计理念是 生命周期感知(Lifecycle-aware)。它遵循观察者模式,当底层数据发生变化时,自动通知所有处于活跃状态(STARTED 或 RESUMED)的观察者。非活跃观察者不会收到回调,从而杜绝空指针和内存泄漏。
关键机制:LiveData 内部维护一个 LifecycleOwner 的弱引用,通过 LifecycleRegistry 监听生命周期事件,在 onDestroy 时自动移除观察者。
- setValue(T):在主线程更新数据,同步通知观察者。
- postValue(T):在后台线程更新数据,将更新任务 post 到主线程执行。
- observe(LifecycleOwner, Observer):绑定生命周期,自动管理订阅。
- observeForever(Observer):不绑定生命周期,需手动调用 removeObserver()。
// 典型用法:ViewModel 中暴露 LiveData
class MyViewModel : ViewModel() {
private val _name = MutableLiveData<String>()
val name: LiveData<String> get() = _name
fun updateName(newName: String) {
_name.value = newName // 主线程更新
}
}
// Activity 中观察
viewModel.name.observe(this) { value ->
textView.text = value
}
典型使用场景
| 场景 | 说明 |
|---|---|
| UI 数据绑定 | Activity / Fragment 通过 observe() 监听 ViewModel 暴露的 LiveData,自动更新 UI。 |
| 列表数据驱动 | 配合 RecyclerView 使用,数据变化时自动刷新列表。 |
| 跨组件数据共享 | 多个 Fragment 共享同一个 ViewModel 的 LiveData,实现数据同步。 |
| 事件一次消费 | 通过 SingleLiveEvent 或 Event 包装类实现 toast、导航等一次性事件。 |
现有架构中的位置
在官方推荐的 MVVM 架构 中,LiveData 充当 ViewModel 层与 View 层之间的桥梁。ViewModel 从 Repository 获取数据,转换成 LiveData 暴露给 View 层,View 层通过 observe 订阅变化。同时 LiveData 也常用于 Repository 内部连接 Room 数据库,因为 Room 原生支持返回 LiveData。
LiveData 的局限性(为何考虑迁移到 Flow)
已知短板:
- 所有转换(map、switchMap)只能通过 MediatorLiveData 手动实现,缺乏声明式操作符。
- 不支持线程切换(observe 始终回调主线程),无法利用背压处理高频率数据流。
- 事件一次性消费需额外封装(如 SingleLiveEvent),容易误用导致黏性事件问题。
- 单元测试需依赖 InstantTaskExecutorRule,测试弹性不如 Flow 的冷流/热流组合。
LiveData 常用 API 速查表
| API | 作用 | 线程 |
|---|---|---|
setValue(T) | 更新数据并同步通知 | 主线程 |
postValue(T) | 更新数据,在主线程通知 | 任意线程 |
observe(LifecycleOwner, Observer) | 绑定生命周期的订阅 | 主线程回调 |
observeForever(Observer) | 非生命周期感知订阅 | 主线程回调 |
MediatorLiveData | 合并多个 LiveData 源 | 依赖 addSource |
Transformations.map() | 对 LiveData 数据变换 | 链式,主线程 |
Transformations.switchMap() | 根据 LiveData 的值切换数据源 | 链式,主线程 |