kotlin启动协程源码分析

   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);
   }


   

猜你喜欢

转载自blog.csdn.net/baidu_24392053/article/details/141104940