当前位置: 首页 > news >正文

Channel 与 callbackFlow:Google 为什么还要设计第三套模型?—— 从 State、Event 到 Queue,彻底串起 Kotlin Flow 体系

引言

上一篇我们讲了:

《StateFlow 与 SharedFlow:Google 为什么要设计两套 Flow?》

我们知道了:

StateFlow -> State(状态) SharedFlow -> Event(事件)

很多同学学到这里会产生一个新的疑问:

既然 SharedFlow 都能发事件了, 为什么 Kotlin 协程里还有 Channel? callbackFlow 又是什么? 它们和 SharedFlow 有什么区别?

说实话,

以前我也一直觉得:

StateFlow SharedFlow 够用了

直到最近重新梳理 Flow 体系,

突然发现:

Google 设计的其实并不是几个 API。

而是几种完全不同的数据传递模型。

今天我们就把这条线彻底串起来。


一、先回顾上一篇

上一篇我们得出了一个重要结论:

StateFlow

解决:

现在是什么状态?

例如:

loading userInfo pageState

本质:

State(状态)

SharedFlow

解决:

刚刚发生了什么事件?

例如:

Toast Navigation LoginSuccess

本质:

Event(事件)

那么问题来了:

为什么还有 Channel?

二、SharedFlow 已经能发事件了,为什么还要 Channel?

很多人第一次看到 Channel 的时候都会觉得:

这玩意是不是多余?

因为:

SharedFlow

已经能:

发送事件 接收事件

看起来什么都能做。

实际上:

SharedFlow 和 Channel 解决的是两种完全不同的问题。


三、从现实世界理解三种模型

StateFlow —— 黑板

想象一个教室。

黑板上写着:

当前温度:25℃

后来进来的学生:

也能看到25℃

因为:

状态永远存在

这就是:

StateFlow

SharedFlow —— 广播

老师说:

今天下午停课

全班同学都听到了。

特点:

一个发送者 多个接收者

这就是:

SharedFlow

Channel —— 消息队列

现在老师发作业。

每发一份:

被一个同学拿走

拿走以后:

别人就拿不到了

特点:

一条消息 只被消费一次

这就是:

Channel

四、我突然发现:这不就是 MQ 吗?

学到这里,我脑子里突然蹦出一个想法:

这特么不就是 MQ 吗?

其实非常像。

共同模型:

Producer ↓ Queue ↓ Consumer

例如:

RabbitMQ RocketMQ Kafka

都是这样。


但区别也很明显。

MQ:

跨进程 跨服务器 可持久化

而:

Channel

只是:

同一个进程内 协程之间 内存级消息队列

所以可以简单理解:

Channel = 协程版 MQ

五、Android 为什么很少用 Channel?

很多同学学完 Channel 后会发现:

项目里几乎没见过

原因很简单。

大多数 Android 场景:

StateFlow SharedFlow

已经够用了。

例如:

Loading PageState Toast Navigation

根本不需要:

消息队列

所以实际项目大致是:

90% StateFlow 9% SharedFlow 1% Channel

六、callbackFlow 又是什么?

学到这里,又会冒出一个新问题:

callbackFlow 是什么?

例如:

定位监听

蓝牙监听

传感器监听

WebSocket监听

这些 API 长这样:

setListener { ... }

属于:

Callback 模型

但 Kotlin Flow 希望你:

collect

怎么办?


七、callbackFlow 本质是什么?

答案其实非常优雅。

Google 给我们做了一个桥梁:

callbackFlow

例如:

fun locationFlow() = callbackFlow { val listener = object : LocationListener { override fun onLocationChanged(location: Location) { trySend(location) } } register(listener) awaitClose { unregister(listener) } }

这样:

Callback

就变成了:

Flow

八、callbackFlow 底层到底干了什么?

理解这一张图就够了。

Callback ↓ Channel ↓ Flow ↓ collect

也就是说:

外部回调来了 ↓ 塞进 Channel ↓ 转换成 Flow ↓ Collector 消费

这也是为什么:

callbackFlow

里面最常见的是:

trySend()

而不是:

emit()

因为它本质上就是:

Callback + Channel

九、Flow 体系终于串起来了

到这里,

我突然发现以前学的知识终于连成了一张图。

Flow │ ├── StateFlow │ └── State │ ├── SharedFlow │ └── Event │ ├── Channel │ └── Queue │ └── callbackFlow └── Callback → Queue → Flow

以前我觉得:

StateFlow SharedFlow Channel callbackFlow

是四个 API。

现在发现:

它们其实是在解决四种不同的数据流动方式。


十、最终总结

StateFlow

解决:

现在是什么状态

例如:

Loading UserInfo PageState

SharedFlow

解决:

刚刚发生了什么事件

例如:

Toast Navigation ErrorEvent

Channel

解决:

消息如何排队消费

例如:

任务队列 生产者消费者

callbackFlow

解决:

如何把 Callback 世界接入 Flow 世界

例如:

定位 蓝牙 WebSocket 传感器

结语

回头看这一系列内容,

其实我最大的收获并不是学会了几个 API。

而是终于把过去那些零散的知识串成了一张图。

以前我觉得:

LiveData StateFlow SharedFlow Channel callbackFlow

只是 Android 中不同的数据传递工具。

直到重新梳理 Kotlin Flow 体系之后,我才发现:

它们其实对应着四种完全不同的思维模型

StateFlow -> State(状态) SharedFlow -> Event(事件) Channel -> Queue(队列) callbackFlow -> Callback(回调)

Google 设计的并不是几个类,而是在引导开发者思考:

现在是什么状态? 刚刚发生了什么事件? 消息应该如何排队处理? 传统回调如何接入协程世界?

当理解了这四个模型以后,

再回头看 Flow,

你会发现很多以前觉得复杂的问题,

其实都变得非常自然。


下篇预告

前两篇我们已经建立了完整的理论体系:

State ↓ Event ↓ Queue ↓ Callback

但对于 Android 开发来说,

最常见的问题其实是:

定位监听 蓝牙监听 WebSocket监听 传感器监听 下载进度监听

这些 API 天生都是:

Callback

而我们的业务代码却越来越希望使用:

collect()

那么问题来了:

Google 到底是如何把 Callback 世界转换成 Flow 世界的?

callbackFlow 内部到底做了什么?

trySend 为什么会出现?

它和 Channel 又是什么关系?

下一篇我们继续:

《callbackFlow 实战:如何把定位、蓝牙、WebSocket 回调改造成 Flow?》

从源码到实战,

彻底讲透 Callback → Channel → Flow 的完整链路。

http://www.rkmt.cn/news/1427410.html

相关文章:

  • 东华大学考研辅导班强烈推荐【独峰考研】全解析 - michalwang
  • 计算机控制机器人的四大短板:从程序化思维到系统集成的深层局限
  • AI智能体运营入门全攻略:核心知识、实操技能与学习路径全覆盖
  • 太康锅炉厂家哪家比较好?一篇讲透选择锅炉厂家的所有维度 - 品牌2026
  • 中国科学技术大学考研辅导班强烈推荐【独峰考研】全解析 - michalwang
  • 惠州黄金上门回收平台推荐2026 - 黄金回收
  • Ceph分布式存储核心技术精要与运维实践指南
  • Windows Server 2016评估版总自动关机?别慌,用DISM命令一键转正式版(附序列号)
  • 上海包包回收十大排行榜深度解析(2026年5月) - 薛定谔的梨花猫
  • 2026年昆明代理记账与云南工商变更全生命周期企业财税服务全面测评:5大服务商选型避坑指引 - 企业名录优选推荐
  • 魔兽争霸3性能优化完全指南:用Warcraft Helper免费解锁高帧率体验
  • 创新AI翻唱工具实战指南:用AICoverGen打造专业级AI音乐作品
  • 深度拆解:KTV如何用“免费送酒“策略撬动370万投资
  • 从零上手Juniper SRX300防火墙:手把手配置DHCP、NTP和Web管理(含安全策略)
  • HBase Java API实战:从Shell到代码,手把手教你完成增删改查(附完整项目源码)
  • 别再只盯着路由模式了!天融信防火墙透明模式部署实战,零感知保护内网安全
  • 仿真科普 | 低空经济的“数字风盾”:CFD+数字孪生构建智慧风场仿真体系
  • 从规则引擎到情境感知:构建个性化内容治理系统的技术实践
  • 网易云音乐双语歌词下载终极指南:LrcHelper带你轻松获取完美歌词
  • 加密市场HODL投资哲学:构建信念体系应对波动,实现长期价值增长
  • 智慧树刷课插件终极指南:3分钟解放你的学习时间![特殊字符]
  • 神经渲染相机轨迹优化:从理论到实战的完整指南
  • SMOKE3D的3D框解码全解析:从网络输出的8个数字到KITTI格式的航向角β
  • 2026年618开门红攻略!5月30日晚8点到底怎么买最便宜?全品类优惠券消费券红包国补多重叠加最划算教程汇总 - 资讯快报
  • 滴滴D²-City数据集二次标注实战:手把手教你构建斑马线+行人+交通灯YOLO训练集
  • 别再傻傻用第三方软件了!用PowerShell的Get-CimInstance命令,5分钟生成一份完整的电脑硬件配置报告
  • 3D标签云(tagcloud.js 详解)
  • 电脑shift+delete删除的文件怎么找回,6种恢复技能和视频展示,让你的数据快速恢复!
  • AI原生攻防2026:从大模型漏洞到自主Agent战争,网络安全的范式革命与生存之道
  • 如何快速掌握Ryzen处理器调试:面向初学者的完整硬件调优指南