朱涛 · Kotlin 编程第一课
朱涛
Google 认证的 Kotlin、Android 开发者专家,博客“Kotlin Jetpack 实战”作者
6717 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
朱涛 · Kotlin 编程第一课
15
15
1.0x
00:00/00:00
登录|注册

14 | 如何启动协程?

你好,我是朱涛。
从今天开始,咱们正式进入协程 API 的学习,一起来攻克 Kotlin 当中最关键的部分。这节课呢,我会给你介绍下如何启动协程,主要包括协程的调试技巧、启动协程的三种方式。这些都是学习协程最基本的概念,也是后续学习更多高阶概念的基础。
注意,在这节课当中,我会使用协程 API 编写大量的案例。我也希望你能够打开 IDE,跟着我一起来运行对应的代码。通过这样的方式,你一定会有更多的收获。
好,接下来,让我们直接开始学习吧!

协程调试

想要学好 Kotlin 协程,掌握它的调试技巧很重要。一般来说,我们可以通过两种手段来进行调试:设置 VM 参数、断点调试。

协程 VM 参数

我们先来看第一种。具体的做法呢,其实很简单,我们只需要将 VM 参数设置成“-Dkotlinx.coroutines.debug”。
完成这个设置后,当我们在 log 当中打印“Thread.currentThread().name”的时候,如果当前代码是运行在协程当中的,那么它就会带上协程的相关信息。具体我们可以看个代码的例子:
// 不必关心代码逻辑,关心输出结果即可
fun main() {
GlobalScope.launch(Dispatchers.IO) {
println("Coroutine started:${Thread.currentThread().name}")
delay(1000L)
println("Hello World!")
}
println("After launch:${Thread.currentThread().name}")
Thread.sleep(2000L)
}
/*
输出结果:
After launch:main
Coroutine started:DefaultDispatcher-worker-1 @coroutine#1
*/
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了协程的启动方式和调试技巧。作者首先强调了掌握协程调试技巧的重要性,介绍了通过设置VM参数和使用IDE的断点调试功能两种方式进行协程调试。在设置VM参数方面,作者指出可以通过将VM参数设置成“-Dkotlinx.coroutines.debug”来在log中打印协程相关信息。在断点调试方面,作者提到了升级IDE版本、确保Kotlin编译器插件版本号大于1.4以及为协程代码打断点等注意事项,并展示了相关操作步骤和调试窗口的信息。 接着,作者介绍了启动协程的三种方式:runBlocking、launch和async。runBlocking会阻塞当前线程的执行,适用于连接线程与协程,但不推荐在生产环境中使用。launch是典型的“Fire-and-forget”场景,不会阻塞当前程序的执行流程,但无法直接获取协程的执行结果。而async则结合了launch和runBlocking的优点,不会阻塞当前的执行流程,同时可以直接获取协程的执行结果。 文章通过实例代码和详细解释,帮助读者理解了协程的启动方式和特点,以及协程调试的方法,为读者提供了实用的技术指导。总体而言,本文内容详细、实用,对于想要学习协程的读者来说具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《朱涛 · Kotlin 编程第一课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(31)

  • 最新
  • 精选
  • Allen
    后面思考题的执行结果为: In async .... In async after delay.... 我的思考是 async 类比钓鱼,鱼钩已经扔出去了,钓鱼的这个动作已经开始了,只是我并没有拉杆。

    作者回复: 这个比喻很棒!

    2022-02-14
    5
    28
  • Geek_Adr
    async != lazy await只是等待执行完,并不是触发执行

    作者回复: 总结很到位!

    2022-02-20
    2
    10
  • 面无表情的生鱼片
    老师用“射箭”和“钓鱼”来做比喻真是让人想忘都忘不掉! 不过我有一点关于思考题的反思: 虽然说 `async{}` 是不阻塞的,但是后续 `deferred.await()` 会阻塞。 严格意义上是否可以认为 `async{}` + `deferred.await()` 是阻塞的。 单用 `async()` 而不调用 `deferred.await()` 的情况应该使用 `launch{}`,在这种情况下老师列的表格中标注 `async{}` 是不阻塞是否意义不大?

    作者回复: 你的理解很到位。async{}对比launch{}的不同还是在于返回值,至于`async{}` 是不阻塞其实是对比runBlocking的。

    2022-02-15
    4
    8
  • 魏全运
    思考题: In async:main In.async after delay! 请问这里是有什么让人容易忽略的细节吗?

    作者回复: 有些同学会认为deferred.await()如果不调用的话,async当中的代码就不会执行。

    2022-02-14
    5
    8
  • Gavin
    对于GlobalScope有疑问,阅读了源码注释,也不是很清楚为什么GlobalScope不建议用,能帮忙解释下吗

    作者回复: GlobalScope最大的劣势,就是不具备“结构化并发”的能力。

    2022-02-24
    3
    7
  • 遥远的救世主
    我用 Android Studio Chipmunk | 2021.2.1 Patch 1,设置VM 参数后调试协程名还是不打印,debug也没有协程那一项,Google 开发的工具不给力啊

    作者回复: 你得试试 JetBrains 的 IDE,Android Studio 的版本是落后与 JetBrains 的。

    2022-05-27
    4
  • neo
    你好,既然launch和runBlocking都不建议在生产环境中使用,只能使用async。 但是async也是需要CoroutineScope对象,但是GlobalScope也不建议使用,那我们在生产环境中应该使用怎样的方式来开启协程呢

    作者回复: 只是runBlocking不建议在生产环境使用。如果你是Android开发,官方为你提供了LifecycleScope、ViewModelScope。如果是其他端,则可以自己创建CoroutineScope。

    2022-04-22
    3
    3
  • PoPlus
    思考题:async 函数就像 launch 函数会异步执行,所以会输出结果。 只是 async 函数有个对应的 await 函数可以接收值,这个接收过程是阻塞式的。

    作者回复: 没错~

    2022-02-22
    2
  • ACE_Killer09
    fun main() { GlobalScope.launch { // 1 println("Coroutine started!") // 2 delay(1000L) // 3 println("Hello World!") // 4 } println("After launch!") // 5 Thread.sleep(2000L) // 6 println("Process end!") // 7 } /* 输出结果: After launch! Coroutine started! Hello World! Process end! */ 执行顺序为啥不是 1、5、6、2、3、4、7? 5 比 2 先执行是不是说明启动协程需要时间?

    作者回复: 应该是: 1、5、6、2、3、4、7,你没错。 5 比 2 先执行是不是说明启动协程需要时间?这其实是由一些其他协程参数决定的,你可以参考17讲的内容。

    2022-02-21
    2
    2
  • syz
    @Test fun main2() = runBlocking { val deferred: Deferred<String> = async { println("In async:${Thread.currentThread().name}") delay(1000L) // 模拟耗时操作 println("In async after delay!") println(this@runBlocking.isActive) return@async "Task completed!" } } In async:Test worker @coroutine#2 In async after delay! true 没有delay也会显示,runBlocking执行完还是active,也不会影响内部async的执行

    作者回复: 是的,这位同学很细心。

    2022-04-15
    1
收起评论
显示
设置
留言
31
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部