Flow 全家桶大白话终极对比
我用最简单、最形象、最容易记的方式给你讲清楚Flow / StateFlow / SharedFlow / ChannelFlow 的区别,保证你一次听懂!
1、一句话核心区别
| 类型 | 一句话理解 | 像什么生活物品 |
|---|---|---|
| Flow | 冷流:没人订阅就不发射,一对一 | 水龙头(你不开,水不流) |
| StateFlow | 热流 + 有状态,永远存最新值,粘性 | 电表(永远显示当前度数) |
| SharedFlow | 热流 + 可回放,多订阅共享事件 | 广播(多人同时听) |
| ChannelFlow | 冷流 + 支持背压 + 并发安全 | 快递通道(有序、可控、不丢件) |
逐个人物讲清楚(超通俗)
1. Flow(冷流)
特点:
- 你不订阅 → 它不执行
- 每次订阅都重新开始
- 一对一
- 最基础、最常用
比喻:水龙头你不开(不 collect),水绝对不流。你开一次,流一次。你关了再开,重新流。
使用场景:
网络请求、数据库读取、一次性任务
flow { emit(数据) }
2. StateFlow(有状态的热流)
一句话
永远持有当前最新数据,新订阅者一进来就能拿到当前值,专门用于 UI 状态。
特性
- ✅ 热流
- ✅ 必须有初始值
- ✅ 永远保存最后一个值
- ✅ 粘性:新订阅者自动收到当前值
- ✅ 数据去重(相同值不重复发送)
- ✅ 专用于 UI 显示状态
比喻
电子表你看的时候,永远显示当前时间。
常用场景
ViewModel 暴露给页面的状态(显示内容、加载状态)
kotlin
val uiState = MutableStateFlow(初始状态)
3. SharedFlow(共享事件热流)
一句话
多订阅者共享事件流,可回放历史,专门用于一次性事件。
特性
- ✅ 热流
- ✅ 多订阅者共享(一对多)
- ✅ 可配置回放条数
- ✅ 无初始值,无默认状态
- ✅ 不会自动去重
- ✅ 专用于事件,不是状态
比喻
广播 / 公告一个人发,所有人同时收到。
常用场景
弹窗、跳转、Toast、提示、一次性操作
kotlin
val event = MutableSharedFlow<Event>()
4. ChannelFlow(带通道的冷流)
一句话
基于 Channel 实现的冷流,支持并发发送、支持背压、多线程安全。
特性
- ✅ 冷流
- ✅ 支持并发发送数据
- ✅ 线程安全
- ✅ 支持背压策略(控制数据流速)
- ✅ 可以在外部协程发送数据
- ✅ 比普通 Flow 更强大
比喻
快递通道有序、可控、不丢件、并发派送。
常用场景
多线程并发生产数据、多源数据合并、需要精确背压控制
kotlin
channelFlow {
send(数据)
}
一张表看懂所有区别(超级清晰)
表格
| 类型 | 冷 / 热 | 是否保存数据 | 新订阅者 | 订阅关系 | 核心用途 |
|---|---|---|---|---|---|
| Flow | 冷 | 不保存 | 从头开始 | 一对一 | 网络、数据库 |
| StateFlow | 热 | 保存最新 1 个 | 立刻拿当前值 | 一对多 | UI 状态 |
| SharedFlow | 热 | 可配置保存 N 个 | 可收历史 | 一对多 | UI 事件 |
| ChannelFlow | 冷 | 不保存 | 从头开始 | 一对一 | 并发、背压 |
最实用的开发口诀(背会就够)
- 页面显示什么 → StateFlow
- 页面要做什么 → SharedFlow
- 网络 / 数据库请求 → Flow
- 多线程并发发数据 → ChannelFlow
最终总结(极简版)
- Flow:基础冷流,用于异步任务
- StateFlow:有状态,存 UI 显示
- SharedFlow:共享事件,用于弹窗、跳转
- ChannelFlow:并发安全,支持背压
你平时开发 90% 只用:StateFlow + SharedFlow!