Android 协程 Channel 菜鸟教程


Android 协程 Channel 菜鸟教程(从 0 到能用)

0️⃣ Channel 是什么?(一句话先懂)

Channel 就是协程里的"消息队列 / 管道"

  • 一边 send(发送)
  • 一边 receive(接收)
  • 消息 按顺序 传递
  • 每条消息 只会被消费一次

1️⃣ 为什么 Android 需要 Channel?

在 Android 里,我们经常遇到这些场景:

  • 按钮点击
  • 列表 item 点击
  • 下拉刷新
  • 重试按钮

这些都有一个共同点:

它们是"事件",不是"状态"

类型 特点
状态(State) 可重复、可恢复
事件(Event) 一次性、不可回放

👉 Channel 非常适合装"事件"


2️⃣ Channel vs 你熟的东西

对比 SharedFlow / StateFlow

工具 适合
StateFlow UI 状态
SharedFlow 广播事件
Channel 单次事件 / 指令

3️⃣ 第一个最简单的 Channel 示例

3.1 创建 Channel

kotlin 复制代码
val channel = Channel<String>()

3.2 发送消息

kotlin 复制代码
launch {
    channel.send("Hello")
}

3.3 接收消息

kotlin 复制代码
launch {
    val msg = channel.receive()
    println(msg)
}

输出:

复制代码
Hello

4️⃣ Channel 是"挂起"的(很重要)

send / receive 都是 suspend

kotlin 复制代码
channel.send("hi")     // 可能挂起
channel.receive()      // 可能挂起

所以:

必须在协程里用


5️⃣ Channel 的几种常见容量(重点)

5.1 默认(RENDEZVOUS)

kotlin 复制代码
Channel()
  • 没缓冲
  • send 和 receive 必须"同时在场"
  • 不常用在 UI

5.2 BUFFERED(推荐)

kotlin 复制代码
Channel(Channel.BUFFERED)
  • 有默认缓冲
  • 适合大多数场景

5.3 UNLIMITED(谨慎)

kotlin 复制代码
Channel(Channel.UNLIMITED)
  • 无限缓冲
  • 永远不会阻塞 send
  • ❗可能内存泄漏

5.4 指定容量

kotlin 复制代码
Channel(capacity = 64)

6️⃣ Android 中的典型用法(重点)

ViewModel 接收 UI 事件

6.1 定义 Intent
kotlin 复制代码
sealed interface UiIntent {
    object LoadData : UiIntent
    data class ClickItem(val id: String) : UiIntent
}

6.2 定义 Channel
kotlin 复制代码
private val intentChannel = Channel<UiIntent>(Channel.BUFFERED)

6.3 UI 发送 Intent
kotlin 复制代码
viewModelScope.launch {
    intentChannel.send(UiIntent.LoadData)
}

6.4 ViewModel 处理 Intent
kotlin 复制代码
init {
    viewModelScope.launch {
        intentChannel.consumeAsFlow().collect {
            handleIntent(it)
        }
    }
}

7️⃣ 为什么用 consumeAsFlow()

kotlin 复制代码
intentChannel.consumeAsFlow().collect { ... }

因为:

  • Flow 更好写
  • 支持操作符
  • 自动处理取消

👉 Channel + Flow = 实战标配


8️⃣ Channel 和 Flow 的核心区别

特点 Channel Flow
是否冷流
是否缓存 可选 可选
是否一次性
是否广播

9️⃣ 常见错误(菜鸟最容易踩)

❌ 错误 1:用 Channel 装状态

kotlin 复制代码
Channel<State> // ❌

❌ 错误 2:用 UNLIMITED 不加限制

kotlin 复制代码
Channel(Channel.UNLIMITED) // ❌ 滥用

❌ 错误 3:在 UI 线程直接 receive

kotlin 复制代码
channel.receive() // ❌ 会卡死

🔟 Channel 什么时候不用?

  • 需要 多观察者SharedFlow
  • 需要 保存最后状态StateFlow
  • 只是一次简单回调 → 普通函数

11️⃣ 一句话速记(给菜鸟的)

Channel = 协程里的事件队列
Flow = 数据流
StateFlow = UI 状态


12️⃣ 你现在可以这样用(推荐模板)

kotlin 复制代码
private val intentChannel = Channel<UiIntent>(Channel.BUFFERED)

fun sendIntent(intent: UiIntent) {
    viewModelScope.launch {
        intentChannel.send(intent)
    }
}

init {
    viewModelScope.launch {
        intentChannel.consumeAsFlow().collect {
            handleIntent(it)
        }
    }
}

13️⃣ 总结一句话(最终记住这个)

Channel 是 Android 中处理"一次性 UI 事件"的最简单、最安全的协程工具。


相关推荐
李堇2 小时前
android滚动列表VerticalRollingTextView
android·java
lxysbly3 小时前
n64模拟器安卓版带金手指2026
android
游戏开发爱好者86 小时前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码20356 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥6 小时前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓7 小时前
[JDBC]元数据
android
独行soc7 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能7 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿7 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc7 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮