lifecycleScope.launch
例子

代码的运行顺序应该是one(),two()还是two(),one(),或者是两个调用的时机是随机的,看协程的调度呢?相信很多人都会选择最后一个.但实际无论运行多少次都是下面的结果

并且launch()方法传入的suspend 函数甚至会阻塞主线程,怎么回事儿,这个协程是假的协程?吗!
先说结论
Kotlin的协程在不同的平台有不同的实现方式.本文以我最熟悉的Android平台为例.在Android中,启动一个协程使用Dispatcher.Main.immediate作为调度器的话,如果当前线程是主线程,就会将任务立即在主线程执行,如果是在其它线程中,使用Handler.post()方法分给主线程去执行.
如果是`Dispatcher.Main作为调度器,就会直接使用主线程的Handler.post()去执行.
CoroutineDispatcher:协程调度器

在导入了androidx.lifecycle:lifecycle-runtime-ktx依赖后,可以在Activity中使用lifecycleScope.launch{}启动一个协程,这里默认的上下文就是 EmptyCoroutineContext,因此启动的协程上下文就是
lifecycleScope.coroutineContext+EmptyCoroutineContext
看下lifecycleScope是怎么来的

这样lifecycleScope.launch{}这样启动一个协程默认的调度器就是Dispatcher.Main.immediate
Dispatcher顾名思义就是调度器,在这里就是负责协程的调度功能,导入依赖查看Android平台的Disptcher.Main的最终实现是由HandlerContext实现的

HandlerContext重写了isDispatchNeeded方法

查看isDispatchNeeded的注释可知道如果该方法返回true就会通过dispatch()将协程分发出去,false就会令协程在当前线程恢复,因此Disptcher.Main会始终调用dispather()来进行分发,而Dispatcher.Main.immediate只有在非主线程中会调用dispatch().何时会调用CoroutineDispatcher.isDispatchNeeded()方法呢?通过查看函数调用在DispatchedContinuation.resumeWith()方法中使用到了它.
DispatchedContinuation:协程调度的发起者
这里只关注DispatchedContinuation是如何让协程立即在当前线程恢复的逻辑


executeUnconfined()方法是DispatchedContinuation的一个拓展函数,协程的执行是交给EventLoop处理,它类似Handler的MessageQueue,如果当前线程的队列已满就会使用EventLoop.dispatchUnconfined()将这个协程调度到当前的EventLoop中,否则直接调用runUnconfinedEventLoop()将协程执行
