反编译后代码分析2

电子说

1.3w人已加入

描述

反编译后代码分析

public final class ExampleUnitTest {
   @Test
   public final void addition_isCorrect() {
      Assert.assertEquals(4L, 4L);

      BuildersKt.launch$default((CoroutineScope)GlobalScope.INSTANCE, (CoroutineContext)null, (CoroutineStart)null, (Function2)(new Function2((Continuation)null) {
         int label;

         @Nullable
         public final Object invokeSuspend(@NotNull Object $result) {
            ExampleUnitTest var10000;
            String var2;
            boolean var3;
            Object var4;
            //对应的标志位
            label34: {
               label33: {
                  var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
                  switch(this.label) {
                  case 0:
                     ResultKt.throwOnFailure($result);
                     var2 = "挂起点1开始";
                     var3 = false;
                     System.out.println(var2);
                     this.label = 1;
                     //根据返回值判断是否为挂起函数,如果为挂起函数直接返回
                     // 挂起函数会持有Continuation,挂起函数执行后调用其resumeWith方法,之后就会回到invokeSuspend中
                     if (DelayKt.delay(1000L, this) ** var4) {
                        //协程退出
                        return var4;
                     }
                     break;
                  case 1:
                     //检测上一步也就是delay是否发生异常或者失败,接着执行-----》挂起点1结束
                     ResultKt.throwOnFailure($result);
                     break;
                  case 2:
                     //检测上一步也就是hello是否发生异常或者失败,接着执行-----》挂起点2结束
                     ResultKt.throwOnFailure($result);
                     break label33;
                  case 3:
                     //检测上一步也就是delay是否发生异常或者失败,接着执行-----》挂起点3结束
                     ResultKt.throwOnFailure($result);
                     break label34;
                  case 4:
                     ResultKt.throwOnFailure($result);
                     return Unit.INSTANCE;
                  default:
                     throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
                  }

                  var2 = "挂起点1结束";
                  var3 = false;
                  //打印
                  System.out.println(var2);
                  var10000 = ExampleUnitTest.this;
                  //label增加,表示上一步执行完成,指向下一个该执行的函数体
                  this.label = 2;
                  //检测hello是否为挂起函数
                  if (var10000.hello(this) ** var4) {
                     //协程退出
                     return var4;
                  }
               }

               //退出label33后执行的函数
               var2 = "挂起点2结束";
               var3 = false;
               System.out.println(var2);
               //再次更正
               this.label = 3;
               //检测是否为挂起函数
               if (DelayKt.delay(1000L, this) ** var4) {
                  //直接退出协程
                  return var4;
               }
            }
            //退出label34后执行的函数
            var2 = "挂起点3结束";
            var3 = false;
            System.out.println(var2);
            var10000 = ExampleUnitTest.this;
            this.label = 4;
             //检测是否为挂起函数
            if (var10000.word(this) ** var4) {
               return var4;
            } else {
               return Unit.INSTANCE;
            }
         }


         @NotNull
         public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
            Intrinsics.checkNotNullParameter(completion, "completion");
            Function2 var3 = new constructor>(completion);
            return var3;
         }

         public final Object invoke(Object var1, Object var2) {
            return (()this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
         }
      }), 3, (Object)null);
   }

}

「看完上面的反编译解析会发现还差了两个方法,没错,接下来就是自定的挂起函数的反编译代码,根据上面的分析请读者亲自分析下接下来的这两个函数」

@Nullable
public final Object hello(@NotNull Continuation $completion) {
   Object var10000 = BuildersKt.withContext((CoroutineContext)Dispatchers.getIO(), (Function2)(new Function2((Continuation)null) {
      int label;

      @Nullable
      public final Object invokeSuspend(@NotNull Object $result) {
      Object var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
      switch(this.label) {
         case 0:
         ResultKt.throwOnFailure($result);
         this.label = 1;
         if (DelayKt.delay(1000L, this) ** var4) {
            return var4;
         }
         break;
         case 1:
         ResultKt.throwOnFailure($result);
         break;
         default:
         throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
      }

      String var2 = "hello";
      boolean var3 = false;
      System.out.println(var2);
      return Unit.INSTANCE;
   }

      @NotNull
      public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
      Intrinsics.checkNotNullParameter(completion, "completion");
      Function2 var3 = new constructor>(completion);
      return var3;
   }

      public final Object invoke(Object var1, Object var2) {
      return (()this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
   }
   }), $completion);
   return var10000 ** IntrinsicsKt.getCOROUTINE_SUSPENDED() ? var10000 : Unit.INSTANCE;
}

@Nullable
public final Object word(@NotNull Continuation $completion) {
   Object var10000 = BuildersKt.withContext((CoroutineContext)Dispatchers.getIO(), (Function2)(new Function2((Continuation)null) {
      int label;

      @Nullable
      public final Object invokeSuspend(@NotNull Object $result) {
      Object var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
      switch(this.label) {
         case 0:
         ResultKt.throwOnFailure($result);
         this.label = 1;
         if (DelayKt.delay(1000L, this) ** var4) {
            return var4;
         }
         break;
         case 1:
         ResultKt.throwOnFailure($result);
         break;
         default:
         throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
      }

      String var2 = "word";
      boolean var3 = false;
      System.out.println(var2);
      return Unit.INSTANCE;
   }

      @NotNull
      public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
      Intrinsics.checkNotNullParameter(completion, "completion");
      Function2 var3 = new constructor>(completion);
      return var3;
   }

      public final Object invoke(Object var1, Object var2) {
      return (()this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
   }
   }), $completion);
   return var10000 ** IntrinsicsKt.getCOROUTINE_SUSPENDED() ? var10000 : Unit.INSTANCE;
}

总而言之,言而总之。还是上一篇博客总结的道理,就是不断的invokeSuspend标记标志位和挂起函数调用resumeWith。

文末致辞:

感谢东方月初提供的资料,和在分析协程原理时给予的支持。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分