Kotlin 协程 Flow Api 中的冷流和热流
当然!“冷流”和“热流” 是在使用 Kotlin 协程 Flow 系列 API 时非常核心的两个概念,它们影响你如何获取数据、何时开始、是否会重复执行等。
🔥 热流(Hot Flow)
✅ 定义:
热流(Hot Flow)始终在发出数据,无论有没有观察者(订阅者)在监听。
✅ 特点:
| 特性 | 描述 |
|---|---|
| 独立于观察者 | 数据源一直在工作,即使没有人收集 |
| 不会重新触发 | 新观察者只能接收到当前或未来的数据,无法看到过去的发射 |
| 常见类型 | StateFlow, SharedFlow, Channel, LiveData |
✅ 示例:StateFlow
val stateFlow = MutableStateFlow(0)
stateFlow.value = 1
stateFlow.value = 2
lifecycleScope.launch {
stateFlow.collect {
println("收到:$it") // 收到的是 2
}
}
✅ 即便你 collect 比较晚了,也能马上收到“当前状态”。
❄️ 冷流(Cold Flow)
✅ 定义:
冷流(Cold Flow)只有在被收集(collect)时才开始发射数据,每次 collect 都会重新执行流的逻辑。
✅ 特点:
| 特性 | 描述 |
|---|---|
| 惰性启动 | 没有订阅者时不做任何事情 |
| 每次 collect 都重新执行 | 像函数一样,有输入就有执行 |
| 适合一次性任务 | 比如网络请求、数据库查询 |
| 常见类型 | Flow(默认就是冷流) |
✅ 示例:普通 Flow
val flow = flow {
println("flow 被触发")
emit("Hello")
}
lifecycleScope.launch {
flow.collect {
println("收到:$it")
}
}
输出:
flow 被触发 收到:Hello
✅ 每次 collect,都会重新执行 flow { … } 里的内容。
🔍 热流 vs 冷流:对比表
| 特性 | 冷流 (Flow) | 热流 (StateFlow, SharedFlow) |
|---|---|---|
| 是否立即开始 | ❌ 否,collect 才开始 | ✅ 是,创建后就开始发射 |
| 多次收集是否重新执行 | ✅ 是 | ❌ 否,只能拿到最新值(StateFlow)或事件(SharedFlow) |
| 是否保留最新值 | ❌ 否 | ✅ 是(StateFlow) |
| 适合做什么 | 网络请求、DB、一次性任务 | UI 状态、事件通知 |
| 是否支持生命周期感知 | ❌ 不自动支持 | ❌ 不自动支持(但可结合 repeatOnLifecycle) |
| 类比 | 函数 | 广播、状态机 |
🎯 如何选择?
| 场景 | 推荐 |
|---|---|
| 需要持续监听状态、保存最后一个值 | StateFlow |
| 一次性事件、多观察者订阅 | SharedFlow |
| 请求 API 或数据库 | Flow(冷流) |
| 复杂任务调度 | Channel |
🧠 记忆小技巧
| 冷流 | 像函数:你调我一次,我就执行一次 |
| 热流 | 像广播站:我一直在发,你来我就播给你 |