第三十章:协程与协程的协程(总结)
好,终于到了最后一章。
说实话,写这个系列的过程中,我一直在想最后一章该怎么收尾。讲新东西?没必要。把前面再复述一遍?太啰嗦。后来我想明白了——这一章,应该是一张地图。你学完了所有知识点,现在需要知道它们怎么串起来,未来往哪走,以及路上有哪些坑我已经替你踩过了。
一、协程的演进与未来
Kotlin 协程从 2017 年诞生到现在,变化其实挺大的。我最早接触的时候,还是 experimental 状态,连 flow 都没有。那时候写异步,要么回调嵌套,要么 RxJava 全家桶。
后来协程正式发布,Google 开始推 ViewModelScope、lifecycleScope,整个 Android 的异步写法才算真正统一了。
几个关键节点:
- 1.0 版本(2018):基础协程能力,launch、async、withContext
- Flow 引入(2019):冷流替代 LiveData 和 RxJava 的部分场景
- StateFlow / SharedFlow(2020):热流登场,状态管理有了协程方案
- 结构化并发完善(2021+):SupervisorJob、CoroutineExceptionHandler 成为标配
未来趋势,我个人判断有这几个方向:
- 协程与 Compose 深度融合:snapshotFlow、rememberCoroutineScope 只是开始,未来状态和协程的边界会更模糊
- 多平台统一:KMP 下协程是跨平台异步的唯一解,iOS 端也在逐步完善
- 性能优化:无锁调度、轻量级取消机制,协程本身的开销会越来越小
- 工具链成熟:协程调试、可视化调度、性能分析工具会越来越完善
二、协程的最佳实践总结
这部分是我最想说的。很多同学学完协程语法,写出来的代码还是「伪协程」——该取消的没取消,该切线程的没切,异常一抛就崩。
我总结了几条铁律:
- Scope 跟着生命周期走:Activity 用 lifecycleScope,Fragment 用 viewLifecycleOwner.lifecycleScope,ViewModel 用 viewModelScope。别自己 new CoroutineScope,除非你很清楚自己在干嘛。
- 取消要响应:所有挂起函数都要能响应取消。如果你在 withContext 里做 CPU 密集计算,记得加
ensureActive()。 - 异常处理分两层:全局用 CoroutineExceptionHandler 兜底,局部用 try-catch 或 catch 操作符。别混在一起。
- Flow 用对场景:UI 层用 StateFlow,事件用 SharedFlow,数据流用 Flow + flowOn。别把 Flow 当 LiveData 用。
- 避免 GlobalScope:除非你写的是常驻后台服务,否则别碰 GlobalScope。它不会自动取消,内存泄漏的根源之一。
核心原则一句话:协程是结构化的,你的代码也应该是结构化的。Scope 嵌套、Job 层级、异常传播,这些不是语法糖,是设计哲学。
三、协程的常见问题与解决方案
我在项目里见过太多类似的坑了。挑几个高频的说说。
问题1:协程不执行,或者执行一半停了
原因:Scope 被取消了,或者 Job 被 join 了但没等到。
解决方案:检查 Scope 的生命周期。如果是自定义 Scope,看看有没有调用 cancel()。用 isActive 打日志确认状态。
问题2:Flow 收不到数据
原因:最常见的是 flowOn 用错了,或者 collect 在错误的线程。
解决方案:记住 flowOn 只影响上游,collect 在下游。如果你在 collect 里更新 UI,确保它在主线程。
问题3:异常被吞了
原因:launch 里的异常默认会传播到父协程,但如果父协程是 SupervisorJob,异常会被忽略。
解决方案:用 try-catch 包裹可能抛异常的代码,或者用 catch 操作符。别指望 CoroutineExceptionHandler 能处理所有情况。
问题4:内存泄漏
原因:协程持有 Activity/Fragment 引用,或者 Flow 没有取消收集。
解决方案:用 lifecycleScope 替代 GlobalScope,用 takeWhile 或 cancellable 控制 Flow 的生命周期。
lifecycleScope + Dispatchers.IO + 取消旧协程,问题解决。记住:协程不是银弹,该取消就得取消。
四、协程的学习资源与社区
学协程,光看文档是不够的。我列几个我常看的资源,都是实战派。
| 类型 | 资源名称 | 推荐理由 |
|---|---|---|
| 官方文档 | Kotlin 协程指南 | 最权威,但偏理论,适合查概念 |
| 书籍 | 《Kotlin 协程:核心编程》 | 中文书里讲得最清楚的,有代码有案例 |
| 视频 | Android Developers 官方协程系列 | Google 工程师亲自讲,适合入门 |
| 社区 | Kotlin 中文社区 / Kotlin 协程交流群 | 有问题直接问,回复快,氛围好 |
| 实战项目 | Google 官方 Now in Android | 协程 + Flow + Compose 的最佳实践样板 |
我个人习惯:遇到新问题,先翻官方文档确认概念,再去 GitHub 搜开源项目看别人怎么写的,最后自己写 demo 验证。别一上来就抄代码,协程这东西,不亲手写几遍 cancel 和 exception,永远学不透。
五、知识体系总览
下面这张图,是我对整个协程知识体系的梳理。你可以把它当作学习路线图,也可以当作面试前的复习提纲。
这张图里,基础概念是地基,调度和异常处理是支柱,Flow 和状态管理是上层建筑,最佳实践是装修标准。缺了哪一层,房子都不稳。
写在最后
30 章,说长不长,说短不短。我写的时候尽量把每个知识点都结合真实场景来讲,因为我知道,大家学协程不是为了考试,是为了解决实际问题。
如果你能把协程的「结构化并发」这个理念吃透,那不管未来 Kotlin 怎么变,Flow 怎么升级,你都能快速上手。因为底层逻辑没变——异步代码应该像同步代码一样好写、好读、好维护。
好了,课程到这里就结束了。感谢你一路读下来。如果哪天你在项目里遇到协程的坑,欢迎来交流。毕竟,踩坑才是最好的学习方式,对吧?
最后送大家一句话:协程不是魔法,是工具。工具好不好用,取决于你懂不懂它。希望这 30 章,能让你真正「懂」协程。