MainScope().launch {
Log.e("test","MainScope().launch ! thread = "+Thread.currentThread())
withContext(Dispatchers.IO){
/**
* withContext(Dispatchers.IO) start thread = Thread[DefaultDispatcher-worker-1,5,main]
*/
Log.e("test","withContext(Dispatchers.IO) start thread = "+Thread.currentThread())
testWithContext()
/**
* withContext(Dispatchers.IO) end thread = Thread[DefaultDispatcher-worker-5,5,main]
* 协程在IO非主线程时,遇到withContext切换,并不保证withContext执行结束后面的代码执行在同一子线程,这里就发现完全不同线程了
* 但是保证执行顺序,widthContext本质上是封装回调嵌套去执行
*/
Log.e("test","withContext(Dispatchers.IO) end thread = "+Thread.currentThread())
}
Log.e("test","MainScope().end ! thread = "+Thread.currentThread())
}
kotlin代码会被编译为字节码
BuildersKt.launch$default(CoroutineScopeKt.MainScope(), (CoroutineContext)null, (CoroutineStart)null, (Function2)(new Function2((Continuation)null) {
int label;
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
Object var2 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
switch (this.label) {
case 0:
ResultKt.throwOnFailure($result);
Log.e("test", "MainScope().launch ! thread = " + Thread.currentThread());
CoroutineContext var10000 = (CoroutineContext)Dispatchers.getIO();
Function2 var10001 = (Function2)(new Function2((Continuation)null) {
int label;
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
Object var2 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
switch (this.label) {
case 0:
ResultKt.throwOnFailure($result);
Log.e("test", "withContext(Dispatchers.IO) start thread = " + Thread.currentThread());
MainActivity var10000 = MainActivity.this;
this.label = 1;
if (var10000.testWithContext(this) == var2) {
return var2;
}
break;
case 1:
ResultKt.throwOnFailure($result);
break;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
return Boxing.boxInt(Log.e("test", "withContext(Dispatchers.IO) end thread = " + Thread.currentThread()));
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
Function2 var3 = new <anonymous constructor>(completion);
return var3;
}
public final Object invoke(Object var1, Object var2) {
return ((<undefinedtype>)this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
});
this.label = 1;
if (BuildersKt.withContext(var10000, var10001, this) == var2) {
return var2;
}
break;
case 1:
ResultKt.throwOnFailure($result);
break;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
Log.e("test", "MainScope().end ! thread = " + Thread.currentThread());
return Unit.INSTANCE;
}
@NotNull
public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
Intrinsics.checkNotNullParameter(completion, "completion");
Function2 var3 = new <anonymous constructor>(completion);
return var3;
}
public final Object invoke(Object var1, Object var2) {
return ((<undefinedtype>)this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
}), 3, (Object)null);
BuildersKt.launch$default方法,如下在BuildersKt这个类里面
public static Job launch$default(CoroutineScope var0, CoroutineContext var1, CoroutineStart var2, Function2 var3, int var4, Object var5) {
return BuildersKt__Builders_commonKt.launch$default(var0, var1, var2, var3, var4, var5);
}
调用到 BuildersKt__Builders_commonKt.launch$default这个方法
public static Job launch$default(CoroutineScope var0, CoroutineContext var1, CoroutineStart var2, Function2 var3, int var4, Object var5) {
if ((var4 & 1) != 0) {
var1 = (CoroutineContext)EmptyCoroutineContext.INSTANCE;
}
if ((var4 & 2) != 0) {
var2 = CoroutineStart.DEFAULT;
}
return BuildersKt.launch(var0, var1, var2, var3);
}
参数说明
CoroutineScope var0,作用域 CoroutineContext var1, CoroutineStart var2, Function2 var3, 两个参数的一个返回值的函数 int var4, 模式 int UNDECIDED = 0; int SUSPENDED = 1; int RESUMED = 2; Object var5,对象
从上面mainActivity反编译代码可知,int var4参数是传了3进来
//3&1 = 0011 & 0001 = 0001 = 1 不为0,则为SUSPENDED 支持挂起 //3&2 = 0011 & 0010 = 0010 = 2 不为0,则为RESUMED 支持恢复执行
由此可知,条件均被命中
if ((var4 & 1) != 0) {
var1 = (CoroutineContext)EmptyCoroutineContext.INSTANCE;
}
if ((var4 & 2) != 0) {
var2 = CoroutineStart.DEFAULT;
}
传递CoroutineStart.DEFAULT,是个枚举类,同时有个invode方法
后续继续调用回到BuildersKt.luanch方法
@NotNull
public static final Job launch(@NotNull CoroutineScope $this$launch, @NotNull CoroutineContext context, @NotNull CoroutineStart start, @NotNull Function2 block) {
return BuildersKt__Builders_commonKt.launch($this$launch, context, start, block);
}
又回到BuildersKt__Builders_commonKt.launch这个方法
@NotNull
public static final Job launch(@NotNull CoroutineScope $this$launch, @NotNull CoroutineContext context, @NotNull CoroutineStart start, @NotNull Function2 block) {
CoroutineContext newContext = CoroutineContextKt.newCoroutineContext($this$launch, context);
StandaloneCoroutine coroutine = start.isLazy() ? (StandaloneCoroutine)(new LazyStandaloneCoroutine(newContext, block)) : new StandaloneCoroutine(newContext, true);
coroutine.start(start, coroutine, block);
return (Job)coroutine;
}
复现一个CoroutineContext,创建一个 StandaloneCoroutine,然后调用start 启动协程
AbstractCoroutine 抽象类的start方法,调用到CoroutineStart.start方法
block是编译期生成的函数fuction2, receiver是StandaloneCoroutine,然后 completion参数是复制生成的新的CoroutineContext 。
public final void start(@NotNull CoroutineStart start, Object receiver, @NotNull Function2 block) {
start.invoke(block, receiver, (Continuation)this);
}
由上面可知传进来的是 CoroutineStart.DEFAULT,内部有个invoke方法,CoroutineStart是个枚举值,这里的值是1,会执行
CancellableKt.startCoroutineCancellable$default(block, receiver, completion, (Function1)null, 4, (Object)null);
@InternalCoroutinesApi
public final void invoke(@NotNull Function2 block, Object receiver, @NotNull Continuation completion) {
switch (CoroutineStart.WhenMappings.$EnumSwitchMapping$0[this.ordinal()]) {
case 1:
CancellableKt.startCoroutineCancellable$default(block, receiver, completion, (Function1)null, 4, (Object)null);
break;
case 2:
ContinuationKt.startCoroutine(block, receiver, completion);
break;
case 3:
UndispatchedKt.startCoroutineUndispatched(block, receiver, completion);
case 4:
break;
default:
throw new NoWhenBranchMatchedException();
}
}
CancellableKt.startCoroutineCancellable$default(block, receiver, completion, (Function1)null, 4, (Object)null);
public static void startCoroutineCancellable$default(Function2 var0, Object var1, Continuation var2, Function1 var3, int var4, Object var5) {
if ((var4 & 4) != 0) {
var3 = null;
}
startCoroutineCancellable(var0, var1, var2, var3);
}
继续调用执行到
public static final void startCoroutineCancellable(@NotNull Function2 $this$startCoroutineCancellable, Object receiver, @NotNull Continuation completion, @Nullable Function1 onCancellation) {
int $i$f$runSafely = false;
try {
int var5 = false;
Continuation var10000 = IntrinsicsKt.intercepted(IntrinsicsKt.createCoroutineUnintercepted($this$startCoroutineCancellable, receiver, completion));
Result.Companion var10001 = Result.Companion;
DispatchedContinuationKt.resumeCancellableWith(var10000, Result.constructor-impl(Unit.INSTANCE), onCancellation);
} catch (Throwable var7) {
dispatcherFailure(completion, var7);
}
}
IntrinsicsKt.intercepted 意思把function2包装一个拦截器,决定是否拦截执行。拦截器的核心实现就是线程分发逻辑,有不同的实现。
会调用到 ContinuationImpl
@SinceKotlin("1.3")
public actual fun <T> Continuation<T>.intercepted(): Continuation<T> =
(this as? ContinuationImpl)?.intercepted() ?: this
其内部方法是,取出CoroutineDispatcher,也就是MainScope的实现类HandlerContext
public fun intercepted(): Continuation<Any?> =
intercepted
?: (context[ContinuationInterceptor]?.interceptContinuation(this) ?: this)
.also { intercepted = it }
取出 ContinuationInterceptor去执行interceptContinuation方法。
实现类的是CoroutineDispatcher实现在这个拦截逻辑,返回了一个DispatchedContinuation
@NotNull
public final Continuation interceptContinuation(@NotNull Continuation continuation) {
return (Continuation)(new DispatchedContinuation(this, continuation));
}
回到startCoroutineCancellable方法
IntrinsicsKt.createCoroutineUnintercepted 创建一个不拦截执行的Continuation,基中$this$startCoroutineCancellable是编译期生成的代码function2传入的
、
然后调用这个 DispatchedContinuationKt.resumeCancellableWith 执行续体
最后调用 $this$resumeCancellableWith.resumeWith(result);
这个$this$resumeCancellableWith就是IntrinsicsKt.intercepted创建的Continuation
也就是DispatchedContinuation.resumeWith(result);开始分发
public void resumeWith(@NotNull Object result) {
CoroutineContext context = this.continuation.getContext();
Object state = CompletionStateKt.toState$default(result, (Function1)null, 1, (Object)null);
if (this.dispatcher.isDispatchNeeded(context)) {
this._state = state;
this.resumeMode = 0;
this.dispatcher.dispatch(context, (Runnable)this);
} else {
int mode$iv = 0;
boolean doYield$iv = false;
int $i$f$executeUnconfined = false;
if (DebugKt.getASSERTIONS_ENABLED()) {
int var8 = false;
if (false) {
throw new AssertionError();
}
}
EventLoop eventLoop$iv = ThreadLocalEventLoop.INSTANCE.getEventLoop$kotlinx_coroutines_core();
if (eventLoop$iv.isUnconfinedLoopActive()) {
this._state = state;
this.resumeMode = mode$iv;
eventLoop$iv.dispatchUnconfined((DispatchedTask)this);
} else {
DispatchedTask $this$runUnconfinedEventLoop$iv$iv = (DispatchedTask)this;
int $i$f$runUnconfinedEventLoop = false;
eventLoop$iv.incrementUseCount(true);
try {
int var11 = false;
CoroutineContext context$iv = this.getContext();
Object countOrElement$iv = this.countOrElement;
int $i$f$withCoroutineContext = false;
Object oldValue$iv = ThreadContextKt.updateThreadContext(context$iv, countOrElement$iv);
try {
int var16 = false;
this.continuation.resumeWith(result);
Unit var17 = Unit.INSTANCE;
} finally {
ThreadContextKt.restoreThreadContext(context$iv, oldValue$iv);
}
while(eventLoop$iv.processUnconfinedEvent()) {
}
} catch (Throwable var26) {
$this$runUnconfinedEventLoop$iv$iv.handleFatalException(var26, (Throwable)null);
} finally {
eventLoop$iv.decrementUseCount(true);
}
}
}
这里Dispatch实现类是HandleContext,是需要分发的,所以会执行下面的方法
HandleContext.dispatch
public void dispatch(@NotNull CoroutineContext context, @NotNull Runnable block) {
if (!this.handler.post(block)) {
this.cancelOnRejection(context, block);
}
}
其中参数是的runnable是DispatchedContinuation自己实现run接口
DispatchedContinuation extends DispatchedTask
在父类的DispatchedTask的run方法里
public final void run() {
if (DebugKt.getASSERTIONS_ENABLED()) {
int var1 = false;
if (this.resumeMode == -1) {
throw new AssertionError();
}
}
TaskContext taskContext = this.taskContext;
Throwable fatalException = null;
boolean var25 = false;
Object countOrElement$iv;
boolean $i$f$withContinuationContext;
Result.Companion var10000;
label355: {
try {
var25 = true;
DispatchedContinuation delegate = (DispatchedContinuation)this.getDelegate$kotlinx_coroutines_core();
Continuation continuation = delegate.continuation;
countOrElement$iv = delegate.countOrElement;
$i$f$withContinuationContext = false;
CoroutineContext context$iv = continuation.getContext();
Object oldValue$iv = ThreadContextKt.updateThreadContext(context$iv, countOrElement$iv);
UndispatchedCoroutine undispatchedCompletion$iv = oldValue$iv != ThreadContextKt.NO_THREAD_ELEMENTS ? CoroutineContextKt.updateUndispatchedCompletion(continuation, context$iv, oldValue$iv) : (UndispatchedCoroutine)null;
try {
int var10 = false;
CoroutineContext context = continuation.getContext();
Object state = this.takeState$kotlinx_coroutines_core();
Throwable exception = this.getExceptionalResult$kotlinx_coroutines_core(state);
Job job = exception == null && DispatchedTaskKt.isCancellableMode(this.resumeMode) ? (Job)context.get((CoroutineContext.Key)Job.Key) : null;
Result.Companion var10001;
if (job != null && !job.isActive()) {
CancellationException cause = job.getCancellationException();
this.cancelCompletedResult$kotlinx_coroutines_core(state, (Throwable)cause);
int $i$f$resumeWithStackTrace = false;
var10001 = Result.Companion;
int $i$f$recoverStackTrace = false;
continuation.resumeWith(Result.constructor-impl(ResultKt.createFailure(DebugKt.getRECOVER_STACK_TRACES() && continuation instanceof CoroutineStackFrame ? StackTraceRecoveryKt.access$recoverFromStackFrame((Throwable)cause, (CoroutineStackFrame)continuation) : (Throwable)cause)));
} else if (exception != null) {
var10001 = Result.Companion;
continuation.resumeWith(Result.constructor-impl(ResultKt.createFailure(exception)));
} else {
var10001 = Result.Companion;
continuation.resumeWith(Result.constructor-impl(this.getSuccessfulResult$kotlinx_coroutines_core(state)));
}
Unit var43 = Unit.INSTANCE;
} finally {
if (undispatchedCompletion$iv == null || undispatchedCompletion$iv.clearThreadContext()) {
ThreadContextKt.restoreThreadContext(context$iv, oldValue$iv);
}
}
var25 = false;
break label355;
} catch (Throwable var36) {
fatalException = var36;
var25 = false;
} finally {
if (var25) {
Object var40;
try {
var10000 = Result.Companion;
int var42 = false;
taskContext.afterTask();
var40 = Result.constructor-impl(Unit.INSTANCE);
} catch (Throwable var32) {
var10000 = Result.Companion;
var40 = Result.constructor-impl(ResultKt.createFailure(var32));
}
this.handleFatalException(fatalException, Result.exceptionOrNull-impl(var40));
}
}
try {
var10000 = Result.Companion;
$i$f$withContinuationContext = false;
taskContext.afterTask();
countOrElement$iv = Result.constructor-impl(Unit.INSTANCE);
} catch (Throwable var33) {
var10000 = Result.Companion;
countOrElement$iv = Result.constructor-impl(ResultKt.createFailure(var33));
}
this.handleFatalException(fatalException, Result.exceptionOrNull-impl(countOrElement$iv));
return;
}
DispatchedTask var39 = this;
try {
var10000 = Result.Companion;
DispatchedTask $this$run_u24lambda_u2d2 = (DispatchedTask)var39;
$i$f$withContinuationContext = false;
taskContext.afterTask();
countOrElement$iv = Result.constructor-impl(Unit.INSTANCE);
} catch (Throwable var34) {
var10000 = Result.Companion;
countOrElement$iv = Result.constructor-impl(ResultKt.createFailure(var34));
}
this.handleFatalException(fatalException, Result.exceptionOrNull-impl(countOrElement$iv));
}
关键方法是,取出代理的continuation去执行恢复。
continuation.resumeWith(Result.constructor-impl(this.getSuccessfulResult$kotlinx_coroutines_core(state)));
最后是执行基类的 BaseContinuationImpl.resumeWith
核心调用逻辑。
public final void resumeWith(@NotNull Object result) {
Object current = null;
current = this;
Object param = null;
param = result;
while(true) {
DebugProbesKt.probeCoroutineResumed((Continuation)current);
BaseContinuationImpl $this$resumeWith_u24lambda_u240 = (BaseContinuationImpl)current;
int var6 = false;
Continuation var10000 = $this$resumeWith_u24lambda_u240.completion;
Intrinsics.checkNotNull(var10000);
Continuation completion = var10000;
Object outcome;
Result.Companion var12;
try {
outcome = $this$resumeWith_u24lambda_u240.invokeSuspend(param);
if (outcome == IntrinsicsKt.getCOROUTINE_SUSPENDED()) {
return;
}
var12 = Result.Companion;
outcome = Result.constructor-impl(outcome);
} catch (Throwable var11) {
var12 = Result.Companion;
outcome = Result.constructor-impl(ResultKt.createFailure(var11));
}
$this$resumeWith_u24lambda_u240.releaseIntercepted();
if (!(completion instanceof BaseContinuationImpl)) {
completion.resumeWith(outcome);
return;
}
current = completion;
param = outcome;
}
}
outcome = $this$resumeWith_u24lambda_u240.invokeSuspend(param); 调用,然后递归调用
$this$resumeWith_u24lambda_u240这个是之前的CancellableKt.startCoroutineCancellable
代码创建的
IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$3
调用执行核心代码是这个,最终调用在MainActivity传入的Function2的invoke方法,执行的代码逻辑
@Nullable
protected Object invokeSuspend(@NotNull Object result) {
Object var10000;
switch (this.label) {
case 0:
this.label = 1;
ResultKt.throwOnFailure(result);
Continuation it = (Continuation)this;
int var3 = false;
Intrinsics.checkNotNull(this.$this_createCoroutineUnintercepted$inlined, "null cannot be cast to non-null type kotlin.Function2<R of kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt.createCoroutineUnintercepted$lambda$1, kotlin.coroutines.Continuation<T of kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt.createCoroutineUnintercepted$lambda$1>, kotlin.Any?>");
var10000 = ((Function2)TypeIntrinsics.beforeCheckcastToFunctionOfArity(this.$this_createCoroutineUnintercepted$inlined, 2)).invoke(this.$receiver$inlined, it);
break;
case 1:
this.label = 2;
ResultKt.throwOnFailure(result);
var10000 = result;
break;
default:
throw new IllegalStateException("This coroutine had already completed".toString());
}
return var10000;
}
回调到MainActivity的方法invoke
public final Object invoke(Object var1, Object var2) {
return ((<undefinedtype>)this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
}
最终执行到
public final Object invokeSuspend(@NotNull Object $result) 方法逻辑。此方法是个状态机,label是状态标志位。执行0逻辑,把状态+1,同时执行withContext逻辑,这里挂起了,立即返回。
withContext执行另一个funtion2,同时把自己传进入,在执行另一个function结束后,会再次执行自己的2逻辑,判断是否有异常,没有异常,则执行后续代码。
本质上封装了Fuction2的,进行分发线程执行,根据状态机可能会再次执行Fuction2回来执行下一段代码。是kotlin帮我们编译器完成了封装。
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
Object var2 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
switch (this.label) {
case 0:
ResultKt.throwOnFailure($result);
Log.e("test", "withContext(Dispatchers.IO) start thread = " + Thread.currentThread());
MainActivity var10000 = MainActivity.this;
this.label = 1;
if (var10000.testWithContext(this) == var2) {
return var2;
}
break;
case 1:
ResultKt.throwOnFailure($result);
break;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
return Boxing.boxInt(Log.e("test", "withContext(Dispatchers.IO) end thread = " + Thread.currentThread()));
}
总结就是kotlin在协程是一个把作用域内的代码封装成一个 Function2,内部是状态机代码,每个协程切换就是一个状态机的分割代码点,使用Continuation的resumeWith方法恢复原来代码的状态机代码的执行。
传入Function2代码,也就是包装了状态机代码块的Function2
1、AbstractCoroutine是最高层级的Continuation,
2、然后包装Function创建一个BaseContinuationImpl(传入(Continuation)AbstractCoroutine)
Continuation var10000 = IntrinsicsKt.intercepted(IntrinsicsKt.createCoroutineUnintercepted($this$startCoroutineCancellable, receiver, completion));
3、然后再利用CoroutineContext的拦截器再包装DispatchedContinuation(传入BaseContinuationImpl),有不同的实现,根据线程类型决定。负责线程分发
4、DispatchedContinuationKt.resumeCancellableWith开始执行,最先执行的是 DispatchedContinuation,把协程分发到指定类型的线程执行run方法,DispatchedContinuation extends DispatchedTask 分发会执行父类DispatchedTask的run方法
5、然后执行 continuation.resumeWith方法,也就是 BaseContinuationImpl的resumeWith方法.
如下,BaseContinuationImpl的实现类实现了invokeSuspend方法的类,一个包装了function2的方法,在invokeSuspend会执行function2的方法,也就是状态机代码块。状态机代码块就真正执行了,也就是官方说的协程
是怎么切换回原先线程的?
看withContext的切换逻辑
@Nullable
public static final Object withContext(@NotNull CoroutineContext context, @NotNull Function2 block, @NotNull Continuation $completion) {
int var4 = false;
CoroutineContext oldContext = $completion.getContext();
CoroutineContext newContext = CoroutineContextKt.newCoroutineContext(oldContext, context);
JobKt.ensureActive(newContext);
Object var10000;
if (newContext == oldContext) {
ScopeCoroutine coroutine = new ScopeCoroutine(newContext, $completion);
var10000 = UndispatchedKt.startUndispatchedOrReturn(coroutine, coroutine, block);
} else if (Intrinsics.areEqual(newContext.get((CoroutineContext.Key)ContinuationInterceptor.Key), oldContext.get((CoroutineContext.Key)ContinuationInterceptor.Key))) {
UndispatchedCoroutine coroutine = new UndispatchedCoroutine(newContext, $completion);
Object countOrElement$iv = null;
int $i$f$withCoroutineContext = false;
Object oldValue$iv = ThreadContextKt.updateThreadContext(newContext, countOrElement$iv);
Object var12;
try {
int var11 = false;
var12 = UndispatchedKt.startUndispatchedOrReturn((ScopeCoroutine)coroutine, coroutine, block);
} finally {
ThreadContextKt.restoreThreadContext(newContext, oldValue$iv);
}
var10000 = var12;
} else {
/**withContext会对作用newContext和oldContext进行判断,如果不是同一类型的线程,
则创建DispatchedCoroutine,也是顶层continuation,DispatchedCoroutine extents ScopeCoroutine extents AbstractCoroutine
**/
DispatchedCoroutine coroutine = new DispatchedCoroutine(newContext, $completion);
CancellableKt.startCoroutineCancellable$default(block, coroutine, (Continuation)coroutine, (Function1)null, 4, (Object)null);
var10000 = coroutine.getResult();
}
if (var10000 == IntrinsicsKt.getCOROUTINE_SUSPENDED()) {
DebugProbesKt.probeCoroutineSuspended($completion);
}
return var10000;
}
withContext会对作用newContext和oldContext进行判断,如果不是同一类型的线程,关注else逻辑,则创建DispatchedCoroutine,也是顶层continuation,
DispatchedCoroutine extents ScopeCoroutine extents AbstractCoroutine
AbstractCoroutine父类的
在执行完子协程之后,调回到最顶级DispatchedCoroutine的resumeWith方法。
public final void resumeWith(@NotNull Object result) {
Object state = this.makeCompletingOnce$kotlinx_coroutines_core(CompletionStateKt.toState$default(result, (Function1)null, 1, (Object)null));
if (state != JobSupportKt.COMPLETING_WAITING_CHILDREN) {
this.afterResume(state);
}
}
在执行先这个子协程后,调用些原协程的context拦截方法创建DispatchedContinuation,分发到原来的线程类型里里。IntrinsicsKt.intercepted是关键方法,取出context实现的拦截器
创建分发线程逻辑,把Continuation回调回原来类型的线程去执行
protected void afterCompletion(@Nullable Object state) {
DispatchedContinuationKt.resumeCancellableWith$default(IntrinsicsKt.intercepted(this.uCont), CompletionStateKt.recoverResult(state, this.uCont), (Function1)null, 2, (Object)null);
}