目录

Kotlin Coroutine 入门(二) - launch/async

Kotlin 协程入门(二) - launch/async

这篇文章是从上一篇文章挂起的, 建议先看上一篇文章: Kotlin Coroutine 入门

我们都知道 suspend 只能在 suspend 函数中使用, 而如果不使用这种方式, 我们往往需要这样做:

1
2
3
4
lifecycleScope.launch {} // Android lifecycleScope
lifecycleScope.async {}
GlobalScope.launch {}
GlobalScope.async {}

在上一篇文章中我们可以了解到, suspend () -> Int 类型在字节码中会转换为 (Continuation) -> Any?, 因此 launch/async 函数实际上就是提供了一个 Continuation 对象

不管是 launch 还是 async, 他们提供的 Continuation 对象都是 AbstractCoroutine, 这就是顶层 Cortinuation 的由来, 他们的 resumeWith 方法就是:

1
2
3
4
5
6
7
8
public final override fun resumeWith(result: Result<T>) {
    val state = makeCompletingOnce(result.toState())
    if (state === COMPLETING_WAITING_CHILDREN) return
    afterResume(state)
}

protected open fun afterResume(state: Any?): Unit = afterCompletion(state)
protected open fun afterCompletion(state: Any?) {}

最终调用了 afterCompletion, 而它的具体实现其实只有三个类:

  1. DispatchedCoroutine: withContext 方法创建出来的, 会阻塞当前协程, 在 withContext 中的耗时任务完成之后, 便会继续执行后续任务.
  2. BlockingCoroutine: runBlocking 方法创建出来的, 不过它可以运行在非 suspend 函数中, 但是不同于 launch/async, 它会直接阻塞当前方法的执行, launch/async 则是启动了新的协程去干这件事
  3. ScopeCoroutine: 也是由 withContext 创建出来的, 当 withContext 与调用之前的 CoroutineContext 一致的时候, 会使用这条快速路径

此时, 我们了解到了顶层协程的启动方式, 我们就可以继续了解 Continuation 在 suspend 中具体是怎么做到的挂起: Kotlin Coroutine 入门 #4-suspend-的实现