Kotlin Flow 是 Android 开发中推荐的异步数据流 解决方案。它基于 Kotlin 协程(Coroutines)构建,功能强大且灵活,旨在替代 RxJava 和部分 LiveData 的使用场景。
我们可以把它理解成一个管道:
上游(Upstream) :负责生产数据(如:从数据库读数据、网络请求)。
中游(Intermediaries) :负责处理数据(如:过滤 filter、转换 map)。
下游(Downstream) :负责接收/消费数据(如:更新 UI)。
核心概念: 冷流VS热流
| 特性 | Cold Flow (普通 Flow) | Hot Flow (StateFlow / SharedFlow) |
|---|---|---|
| 激活时机 | 只有被收集(collect)时才开始运行。 | 无论有无收集者,它都在内存中活跃(类似于 LiveData)。 |
| 数据生产 | 是一对一的(Unicast)。每个收集者都会触发一遍新的数据生产流程。 | 是一对多的(Multicast)。多个收集者共享同一个数据源。 |
| 典型场景 | 耗时的数据库读取、文件下载、简单的异步转换。 | UI 状态管理 (StateFlow)、一次性事件 (SharedFlow)。 |
具体例子:
A. Flow (普通冷流)
最基础的类型。用于执行耗时任务并按顺序发射多个值。
kotlin
// 例子:倒计时
fun countdownFlow(): Flow<Int> = flow {
for (i in 5 downTo 0) {
emit(i) // 发射数据
delay(1000) // 挂起函数,不阻塞线程
}
}
B. StateFlow (热流 - 状态持有者)
它是 LiveData 的现代替代品。
- 特点 :始终持有最新的一个状态值。新的收集者加入时,会立刻收到当前最新的值。
- 场景:用于存储 UI 状态(如:Loading、Success、Error)。
- 对比 LiveData :
StateFlow必须有初始值,且完全支持协程操作符。
kotlin
// ViewModel 中
private val _uiState = MutableStateFlow("Initial State")
val uiState: StateFlow<String> = _uiState.asStateFlow()
// 更新状态
_uiState.value = "New State"
C. SharedFlow (热流 - 事件流)
- 特点 :用于发送一次性事件 (One-off events)。默认不保留旧数据(除非配置
replay),新收集者不会收到过去发出的事件。 - 场景:导航跳转、弹出 Toast、显示 Snackbar、服务器推送消息。
arduino
// ViewModel 中
private val _events = MutableSharedFlow<String>()
val events: SharedFlow<String> = _events.asSharedFlow()
// 发送事件 (suspend function)
_events.emit("Show Toast")
在UI中安全收集
a. 在 Activity / Fragment (使用 Views)
使用 repeatOnLifecycle。它会在特定的生命周期状态(通常是 STARTED)开始收集,在低于该状态(如后台 STOPPED)时自动取消协程,停止接收数据。
javascript
// 在 Activity 或 Fragment 中
lifecycleScope.launch {
// 只有当生命周期至少是 STARTED 时才执行块内代码
repeatOnLifecycle(Lifecycle.State.STARTED) {
// 这两个流会并行收集
launch {
viewModel.uiState.collect { state ->
// 更新 UI
}
}
launch {
viewModel.events.collect { event ->
// 处理事件
}
}
}
}
b. compose
使用 collectAsStateWithLifecycle()。它会自动将 Flow 转换为 Compose 的 State,并感知生命周期。
kotlin
@Composable
fun MyScreen(viewModel: MyViewModel) {
// 需要引入依赖: androidx.lifecycle:lifecycle-runtime-compose
val state by viewModel.uiState.collectAsStateWithLifecycle()
Text(text = state)
}
常用操作符
转换类 :map (数据映射), transform (自定义转换)
过滤类 :filter (过滤), debounce (防抖,搜索框必备), distinctUntilChanged (防重复,StateFlow 默认自带此特性)
组合类 :combine (合并多个流), zip, flatMapLatest (切换流,例如搜索词变化时取消旧请求发新请求)
异常处理 :catch (捕获上游异常)
线程切换 :flowOn(Dispatchers.IO) (指定上游代码在 IO 线程执行)