Flow、StateFlow、SharedFlow和ChannelFlow的区别

7 阅读3分钟

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

最终总结(极简版)

  1. Flow:基础冷流,用于异步任务
  2. StateFlow:有状态,存 UI 显示
  3. SharedFlow:共享事件,用于弹窗、跳转
  4. ChannelFlow:并发安全,支持背压

你平时开发 90% 只用:StateFlow + SharedFlow!