这个问题的目的是了解悬挂方法是如何在引擎盖下工作的,以及
IntrinsicsKt.getCOROUTINE_SUSPENDED();
?
在下面的字节码中,您将看到一段代码
if (var10000.resultingBlockingOp-IoAF18A((Continuation)$continuation) == var4) {
return var4;
}
其中var4是
Object var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
如果函数返回,那么协程将如何执行?
在
invokeSuspend
方法,这是否意味着挂起方法在后台通过递归工作?
class CoroutineExplanatoryUseCase {
private val coroutineExplanatoryRepo: CoroutineExplanatoryRepo = CoroutineExplanatoryRepo()
suspend fun simpleOp() {
coroutineExplanatoryRepo.simpleBlockingOp()
}
suspend fun resultingBlockingOp() {
coroutineExplanatoryRepo.resultingBlockingOp()
}
}
生成的字节码
public final class CoroutineExplanatoryUseCase {
private final CoroutineExplanatoryRepo coroutineExplanatoryRepo = new CoroutineExplanatoryRepo();
@Nullable
public final Object simpleOp(@NotNull Continuation $completion) {
Object var10000 = this.coroutineExplanatoryRepo.simpleBlockingOp($completion);
return var10000 == IntrinsicsKt.getCOROUTINE_SUSPENDED() ? var10000 : Unit.INSTANCE;
}
@Nullable
public final Object resultingBlockingOp(@NotNull Continuation var1) {
Object $continuation;
label20: {
if (var1 instanceof <undefinedtype>) {
$continuation = (<undefinedtype>)var1;
if ((((<undefinedtype>)$continuation).label & Integer.MIN_VALUE) != 0) {
((<undefinedtype>)$continuation).label -= Integer.MIN_VALUE;
break label20;
}
}
$continuation = new ContinuationImpl(var1) {
// $FF: synthetic field
Object result;
int label;
@Nullable
public final Object invokeSuspend(@NotNull Object $result) {
this.result = $result;
this.label |= Integer.MIN_VALUE;
return CoroutineExplanatoryUseCase.this.resultingBlockingOp(this);
}
};
}
Object $result = ((<undefinedtype>)$continuation).result;
Object var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
switch (((<undefinedtype>)$continuation).label) {
case 0:
ResultKt.throwOnFailure($result);
CoroutineExplanatoryRepo var10000 = this.coroutineExplanatoryRepo;
((<undefinedtype>)$continuation).label = 1;
if (var10000.resultingBlockingOp-IoAF18A((Continuation)$continuation) == var4) {
return var4;
}
break;
case 1:
ResultKt.throwOnFailure($result);
((Result)$result).unbox-impl();
break;
default:
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
return Unit.INSTANCE;
}
}