Android | LiveData 与 Flow 的异同点对比

677 阅读3分钟

LiveData & Flow介绍

LiveData 与 Flow 是 Android 中常见的响应式数据持有器,它们都用于将数据的变更通知给观察者,但在设计目标、生命周期绑定、线程模型等方面存在明显差异。

1、LiveData 具有生命周期感知能力,遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的Observer,非活跃状态下的Observer不会受到通知。生命周期状态可以通过Lifecycle提供,包括DESTROYED、INITIALIZED、CREATED、STARTED、RESUMED,当且仅当生命周期处于STARTED、RESUMED时为活跃状态,其他状态是非活跃状态。使用示例:

 // 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 使用。使用示例:

//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 的数据流

不同点

特性LiveDataFlow
生命周期感知内置支持,自动在 Activity/Fragment 销毁时移除观察者不自带,需要手动用 flowWithLifecycle()repeatOnLifecycle()
多个观察者支持多个观察者默认单播,需用 shareInstateIn变成热流之后才可以支持多个观察者
冷热流热流默认冷流,也可变热流
线程安全默认主线程安全需手动指定 withContextflowOn,切换线程很方便
操作符少量(如 Transformations.map()),不支持背压、异常等操作符丰富,转换操作符如 mapflatMapConcatcombine等,支持 buffer()背压操作符、catch 异常处理操作符
可测试性需依赖主线程轻松进行单元测试

使用场景建议

使用场景推荐
UI 层简单数据观察使用 LiveData
响应复杂数据流,组合多个数据源(map/filter/zip)、处理背压、并发、异常等复杂操作使用 Flow
Kotlin 协程已全面使用 / 异步任务 / 可取消任务使用 Flow 更合适

简单总结就是:LiveData 更适合简单UI状态监听;而 Flow / StateFlow 更适合流式编程、复杂异步数据处理

如果在开发新项目,推荐优先使用 StateFlow 替代 LiveData,尤其是使用Jetpack Compose 开发时,Flow 效果更佳。