深入理解Kotlin协程
上QQ阅读APP看书,第一时间看更新

前言

为什么要写这本书

我应该算是国内比较早接触和使用Kotlin的开发者了。

知道这门语言完全是个偶然。当时我还在阿里巴巴实习,周末没事去公司蹭吃蹭喝蹭电脑,编译了Hotspot源码觉得还不过瘾,又开始编译IntelliJ IDEA的社区版。

某天下午我遇到件烦心事,编译并不是很顺利。我发现有一种没见过的后缀为kt的文件,顿时感到压力倍增,Groovy和Scala我还没学会呢,怎么又来一个!不过,当时我只是按照说明把Kotlin的环境搭建好,并没有继续理会这门还处在v0.8的语言。

毕业之后我就职于腾讯地图,得益于团队良好的技术氛围以及对新人的鼓励和信任,入职第一年就能有机会负责重构地图SDK,后来为团队贡献了不少公共组件。整个过程中我既充分感受到了Java的魅力,也发现了它在开发效率上的不足。于是我试着用Groovy、Scala甚至Python来开发Android,但都不太理想,最后想起JetBrains家的“小儿子”Kotlin,结果就一发不可收拾。

Lambda,我所欲也;扩展函数,亦我所欲也。二者居然可兼得。后来我的业余时间也从研究“茴香豆的‘茴’有几种写法”变成了研究“这段Java代码用Kotlin能怎么简化”。可是,当时身边的同事和同行似乎并没有对Java感到疲惫,于是我又开始试着录视频、写文章,最终走上了Kotlin的布道之路。

幸运的是,Kotlin在2017年的Google I/O大会上被提为Android开发的一级语言,这着实让它火了一把。那时候绝大多数Android工程师可能都没有听说过这门语言,它有何德何能竟会受到Google的青睐?

当时,我和几个天天因Kotlin的特性而相互“口诛笔伐”的群友们聚到一起,考虑是否要写本书——大家也许需要这样一本书来了解Kotlin。不过,这本书因写作时间很长,耗尽了大家的热情,我们尚未定稿,国内其他Kotlin入门书已陆续面世。至于我负责的协程部分,从协程还是个“宝宝”开始,先后重写了三次,现在的Kotlin协程俨然是一位“大叔”了。

2019年,机械工业出版社的杨福川老师找到我,问我要不要写点什么。我想,Kotlin协程现在仍然是一个很大的麻烦,国内外都没有很好的资料,官方文档又过于精练,不太适合大家入门和进阶。于是就有了这本书。

Kotlin协程不像Python、JavaScript的async/await那样容易上手,后者似乎根本不需要明白什么是协程就能轻松使用。

我曾试着从Kotlin协程的标准库API开始讲——这样的好处是大家能够打好基础,结果大多数读者反馈这样不易学习。于是在“破解Kotlin协程”系列文章中,我从一开始就基于Kotlin项目组提供的协程框架开始介绍,并对比RxJava从实际问题切入,读者反映这可能是最通俗易懂的协程文章了。不过很快,在介绍到调度器和挂起原理等内容的时候,读者就开始叫苦了,反馈说读起来如同天书一般。

当然,这其中也不乏感觉良好的读者,他们期望我能系统地对比一下Kotlin与其他语言的协程实现的异同,这说明这部分内容本身不是问题,问题可能是铺垫做得不足。于是我仔细分析了读者反馈的问题,发现多数问题源自大家对于协程概念理解的偏差。因此在本书中,我从一开始就紧紧抓住概念问题,从各个角度去阐释什么是协程,以及Kotlin协程与其他常见语言的协程在实现上有何区别。在探讨概念的时候,我尽可能用实际问题引入,逐步给出解决思路,由简入繁,将协程的设计思路和实现细节尽可能地呈现出来。

还有朋友建议我在文章中多提供一些图表以方便理解,为此我在本书中为所有关键节点提供了相应的状态图、时序图等,希望能够帮助读者轻松理解探讨的内容。

读者对象

本书适用于有一定基础的Kotlin开发者,包括但不限于正在使用和希望使用Kotlin开发Android、Web服务、iOS、前端等应用的开发者。

本书不会讲解Kotlin的基础语法,因此建议Kotlin初学者先阅读基础书,《Kotlin核心编程》就是一个不错的选择。你也可以访问https://coding.imooc.com/class/398.html参考我在慕课网发布的“Kotlin入门到精通”视频课程,视频中详细讲解了Kotlin的基础与进阶知识,其中的协程部分可以与本书配套学习。

本书特色

Kotlin协程背后的知识点非常多,本书从异步程序的设计入手,探讨异步程序设计中要面对的关键问题,并在之后围绕这几个关键问题对Kotlin协程的设计实现展开探讨。

在剖析Kotlin协程的过程中,本书除介绍API的基本用法以外,还提供了使用Kotlin协程设计实现各类复合协程API的思路和方法,并抽象出一套系统的设计思路,通过CoroutineLite这个项目的设计实现,帮助大家深入了解官方协程框架的内部运行机制。

在帮助读者掌握Kotlin协程内部原理的同时,本书还从Android、Web应用和多平台等角度提供了实践思路,帮助读者做到在原理上深入浅出,在实战中融会贯通。

为了方便内容的展开,在探讨的过程中本书也对一些概念明确进行了定义和归纳,例如简单协程、复合协程、协程体等。

本书包含了丰富的示例,以便于读者阅读参考。

为提升读者的阅读体验,本书所有代码均采用JetBrains Mono字体,该字体由Kotlin项目团队所属公司JetBrains为开发者专门打造,更适合代码的阅读。

如何阅读这本书

本书基于撰写时的最新Kotlin v1.3.61来讲解Kotlin协程的基本概念、实现原理和实践技巧。全书共9章,具体内容如下。

第1章主要从程序设计出发,结合实际问题引出异步程序的设计方案。异步程序的设计和实现是本书探讨的协程的基本应用场景,也是本书内容的基石。

第2章主要从协程本身切入,剖析协程是什么、有哪些类别,以及不同语言的协程实现有何种区别和联系等。这一章内容是理解Kotlin协程概念的前提。

第3章主要以Kotlin标准库的协程API为核心,阐述简单协程的使用方法和运行机制。简单协程是复合协程的基础,掌握这部分内容是理解协程工作机制的关键。

第4章主要介绍运用Kotlin协程的基础设施设计和实现复合协程的思路和方法,为后续对官方协程框架的学习和运用奠定基础。

第5章以官方协程框架为模板,介绍如何逐步实现其中的核心功能,以帮助读者了解其中的实现细节,并对复合协程的运行机制做到心中有数。这部分内容也是对前几章所述基础知识进行灵活运用的体现。

第6章介绍官方协程框架的运用,重点探讨了Channel、Flow、select的使用场景。至此,我们就已经掌握了将协程运用到实践中的基本技能。

第7章主要探讨协程在以Android为例的UI应用程序开发环境中面临的挑战和解决问题的方法,重点介绍了协程与Android生命周期的结合、协程与RxJava的互调用,以及Retrofit、Room等框架对协程的支持。

第8章主要探讨协程在Web服务开发场景中的运用,重点给出了基于Spring、Vert.x、Ktor这几个框架运用协程解决异步问题的方法和思路。

第9章主要介绍在除JVM以外的JavaScript和Native平台上,Kotlin协程的应用情况。

整体看来,第1~3章侧重于概念的介绍,第4章和第5章侧重于介绍如何将简单协程封装成复合协程,第6章介绍官方框架所提供的复合协程的使用方法,第7~9章侧重于实战运用。

建议对协程不了解的读者从前到后循序渐进地阅读本书。如果对协程有一定的认识,包括有在Lua、Go、JavaScript等语言中使用协程解决异步问题的经验,可以尝试从第6章开始阅读,在遇到不清楚的地方时再有目的地查阅前面的内容。如果想要快速体验协程的魅力,也可以直接从第7章开始挑选自己感兴趣的内容阅读,但全面了解协程的运行机制和原理仍然非常必要。

另外需要说明的是,本书在第2章介绍协程的概念时横向对比了几类典型的协程实现,在第4章中会使用Kotlin仿照这些协程的实现风格给出对应的复合协程实现,这其中涉及Lua、JavaScript、Go等语言,大家不需要对这些语言有更多的认识和了解,只需了解它们的实现形式即可。

勘误和支持

我的水平有限,编写时间仓促,加之技术在不断更新和迭代,所以书中难免会出现一些错误或者不准确的地方,恳请读者批评指正。

大家可以通过以下方式提供反馈。

·关注微信公众号Kotlin,回复“Kotlin协程”,在收到消息的页面评论留言。

·在本书主页https://www.bennyhuo.com/project/kotlin-coroutines.html评论留言。

本书主页会提供勘误表,我会在收到反馈后及时将问题整理补充到勘误表中,对于一些比较重要的问题也会专门通过公众号和我的个人网站提供补充材料。

书中的全部源文件除可以从华章网站(www.hzbook.com)的本书页面下载外,也可以从https://github.com/enbandari/DiveIntoKotlinCoroutines-Sources下载,我会根据相应的功能同步更新代码。如果你有更多的宝贵意见,也欢迎发送邮件至邮箱yfc@hzbook.com,期待你的反馈。

致谢

感谢我的妻子,她是本书的第一位读者,也是第一位认真的校对者,感谢她在我遇到困难时开导和鼓励我,也感谢她在本书的整个写作过程中给予我的陪伴和提出的改进建议。还要感谢我的父母和妹妹,是他们一如既往的支持,才让我在成长过程中敢于尝试和坚持,特别感谢他们容忍我在短暂的春节假期里投入绝大多数的时间来完成书稿。

感谢腾讯地图数据采集研发团队与我并肩作战的战友们,是团队良好的技术氛围为我探索和尝试新技术提供了土壤,当然,也是他们对我很早就在项目中“肆无忌惮”地使用Kotlin进行实践给予了足够的包容。

感谢Kotlin中文社区中每一位有趣的小伙伴,书中不少内容源自大家的切磋探讨,社区的小伙伴用实力为本书内容的组织提供了有力支持。

感谢机械工业出版社华章公司的策划编辑杨福川老师,是他在这半年多的时间里始终支持我写作,鼓励和帮助我顺利完成全部书稿。

谨以此书献给所有Kotlin开发者!

霍丙乾

2020年4月