LiveData & Flow介绍
LiveData 与 Flow 是 Android 中常见的响应式数据持有器,它们都用于将数据的变更通知给观察者,但在设计目标、生命周期绑定、线程模型等方面存在明显差异。
1、LiveData
具有生命周期感知能力,遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的Observer,非活跃状态下的Observer不会受到通知。生命周期状态可以通过Lifecycle提供,包括DESTROYED、INITIALIZED、CREATED、STARTED、RESUMED,当且仅当生命周期处于STARTED、RESUMED时为活跃状态,其他状态是非活跃状态。使用示例:
kotlin
// 1. ViewModel中定义一个 MutableLiveData 用于发送数据
private val _liveData = MutableLiveData<Int>()
val liveData: LiveData<Int> get() = _liveData
fun updateData(value: Int) {
// 2. 更新数据(发送逻辑)
_liveData.value = value
// 或在子线程中使用 postValue(value)
}
//3. UI层接收数据
viewModel.liveData.observe(viewLifecycleOwner) { value ->
textView.text = "当前值是:$value"
}
关于LiveData的详细介绍,参见 Android Jetpack系列之LiveData
2、Flow
是基于kotlin协程的响应式编程模型,它与RxJava的使用类似,但相比之下Flow使用起来更简单,另外Flow作用在协程内,可以与协程的生命周期绑定,当协程取消时,Flow也会被取消,避免了内存泄漏风险。Flow数据流可以按顺序发送多个值,官方对数据流三个成员的定义:1、提供方会生成添加到数据流中的数据;2、通过协程,数据流还可以异步生成数据。中介(可选),修改发送到数据流的值,或修正数据流本身;3、使用方:使用或接收数据流中的值。Flow 默认是一种冷流:延迟执行,只有被 collect 才真正运行,可组合、可操作,支持复杂的流式处理(map、filter、flatMap 等);不依赖 Android 生命周期,但可以配合 lifecycleScope 使用。使用示例:
kotlin
//1、Flow的使用
val dataFlow = flow {
emit(fetchDataFromNetwork()) // 每次 collect 都会执行一次
}
lifecycleScope.launch {
dataFlow.collect { result ->
// 更新 UI
}
}
//2、StateFlow的使用
val _state = MutableStateFlow("")
val state: StateFlow<String> = _state
fun updateData(value: String) {
_state.value = value
}
// UI层订阅
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.state.collect {
// 收到更新
}
}
}
关于Flow的详细介绍,参见:Android Kotlin之Flow数据流
相同点
项目 | 描述 |
---|---|
响应式 | 都支持数据变化时自动通知观察者(观察者模式) |
用于 UI 层 | 都常用于 MVVM / MVI 架构中 ViewModel → UI 的数据流 |
不同点
特性 | LiveData | Flow |
---|---|---|
生命周期感知 | 内置支持,自动在 Activity/Fragment 销毁时移除观察者 | 不自带,需要手动用 flowWithLifecycle() 或 repeatOnLifecycle() |
多个观察者 | 支持多个观察者 | 默认单播,需用 shareIn 或 stateIn 变成热流之后才可以支持多个观察者 |
冷热流 | 热流 | 默认冷流,也可变热流 |
线程安全 | 默认主线程安全 | 需手动指定 withContext 、flowOn ,切换线程很方便 |
操作符 | 少量(如 Transformations.map() ),不支持背压、异常等操作符 |
丰富,转换操作符如 map 、flatMapConcat 、combine 等,支持 buffer()背压操作符、catch 异常处理操作符 |
可测试性 | 需依赖主线程 | 轻松进行单元测试 |
使用场景建议
使用场景 | 推荐 |
---|---|
UI 层简单数据观察 | 使用 LiveData |
响应复杂数据流,组合多个数据源(map/filter/zip)、处理背压、并发、异常等复杂操作 | 使用 Flow |
Kotlin 协程已全面使用 / 异步任务 / 可取消任务 | 使用 Flow 更合适 |
简单总结就是:LiveData 更适合简单UI状态监听;而 Flow / StateFlow 更适合流式编程、复杂异步数据处理。
如果在开发新项目,推荐优先使用 StateFlow
替代 LiveData
,尤其是使用Jetpack Compose 开发时,Flow 效果更佳。