【深入理解Kotlin协程】CoroutineScope.launch源码追踪扒皮

本文深入探讨了Kotlin协程的CoroutineScope.cancel()、launch方法以及上下文组件,包括lifecycleScope、viewModelScope、GlobalScope、MainScope的上下文特性。重点分析了协程启动、挂起与恢复的关键步骤,如SuspendLambda、Continuation.intercepted()和DispatchedContinuation.resumeCancellableWith等。同时,详细解释了withContext()的调度切换过程。
摘要由CSDN通过智能技术生成

lifecycleScope、viewModelScope、GlobalScope、MainScope的上下文

协程最重要的就是协程上下文对象,因为通过上下文可以获取到协程相关的任何东西(Job、Dispatcher、Interceptor、Name、ExceptionHandler),所以有必要了解清楚常用的协程作用域对象中coroutineContext的组成。

lifecycleScope 的协程上下文是 SupervisorJob + Dispatchers.Main.immediate

 viewModelScope 的协程上下文是 SupervisorJob + Dispatchers.Main.immediate,lifecycleScope的一样

GlobalScope 的协程上下文是 EmptyCoroutineContex

MainScope 的协程上下文是 SupervisorJob + Dispatchers.Main

总结就是lifecycleScope、viewModelScope、MainScope这三种协程作用域的上下文组成是 SupervisorJob 加主线程调度器, 而 GlobalScope协程作用域的上下文则是一个空的上下文

CoroutineScope.cancel() 

CoroutineScope 有一个扩展函数 cancel() 可以用来取消内部启动的协程,比如Lifecycle 会在生命周期状态为 DESTROYED 时调用 cancel() 函数取消掉该作用域启动的协程,ViewModel 则会在 clear() 方法中调用 cancel() 函数,对于 Activity 和 Fragment 的 ViewModel ,clear() 方法也是在 destroy 回调里触发的。

来看一下 CoroutineScope.cancel() 方法的实现:

可以看到它是从协程上下文中获取Job对象,然后调用job对象的cancel方法进行取消的,而上面分析的四种Scope中,只有GlobalScope的协程上下文是空的,因此无法从中查询到Job对象,并且它的协程上下文只能获取,也不能通过+运算符设值(val属性),所以GlobalScope无法被cancel,这就是为什么在 Android 中不推荐使用GlobalScope这个作用域来启动协程的原因。

launch方法解析

因为launch是CoroutineScope的一个扩展方法,因此以上四种作用的launch都是同一个方法,如下:

 其中 newCoroutineContext(context) 返回的是 scope作用域上下文 + context参数上下文 + Dispatchers.Default(如果未指定才添加)

上面 coroutine.start 的调用涉及到运算符重载,这里会比较绕,我们只需要知道这里实际上最终会调的是 CoroutineStart.invoke() 方法,在这个方法中根据当前的启动模式去分别执行不同方法,默认的启动模式是DEFAULT, 因此这里走第一个分支。

同时注意到,DEFAULT模式下,这里startCoroutineCancellable方法的receivercompletion参数都是StandaloneCoroutine对象。 在协程体的逻辑执行完后会调用到 completion 的 resume 方法恢复后面的续体代码执行(CPS)。

StandaloneCoroutine 是 AbstractCoroutine的实现类( AbstractCoroutine中会调用initParentJob方法,与父Job建立关联,当调用cancel方法或者子Job有异常时,

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

川峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值