Kotlin协程源码分析-3 调用挂起函数
上文链接 Kotlin协程源码分析-2 调用挂起函数
继续上文从编译后的字节码继续分析,继续查看上篇文章的源码
//com.example.studycoroutine.chapter.two.CoroutineRun.kt
fun testOne(){
val myCoroutineFun: suspend () -> String = {
logD("返回 hello结果")
mySuspendFun()
}
val myCoroutine = MyCoroutine()
//这种写法是下面的封装而已
//myCoroutineFun.startCoroutine(myCoroutine)
val createCoroutine = myCoroutineFun.createCoroutine(myCoroutine)
createCoroutine.resume(Unit)
}
createCoroutine
函数位于kotlin.coroutines.Continuation.kt
查看对应声明
public fun <T> (suspend () -> T).createCoroutine(
completion: Continuation<T>
): Continuation<Unit> =
SafeContinuation(createCoroutineUnintercepted(completion).intercepted(), COROUTINE_SUSPENDED)
SafeContinuation
是一个实现了Continuation
的类,主要用于代理createCoroutineUnintercepted
返回Continuation
。的这里我们不需要理会它,你可以简单理解上述代码等价于
public fun <T> (suspend () -> T).createCoroutine(
completion: Continuation<T>
): Continuation<Unit> =createCoroutineUnintercepted(completion)
createCoroutineUnintercepted
声明
//kotlin.coroutines.intrinsics.CoroutinesIntrinsicsH.kt
@SinceKotlin("1.3")
public expect fun <T> (suspend () -> T).createCoroutineUnintercepted(
completion: Continuation<T>
): Continuation<Unit>
可以看到是一个跨平台类,实现类如下:
//kotlin.coroutines.intrinsics.IntrinsicsKt.class
@SinceKotlin("1.3")
public actual fun <T> (suspend () -> T).createCoroutineUnintercepted(
completion: Continuation<T>
): Continuation<Unit> {
//probeCompletion 还是我们传入completion对象,在我们的Demo就是myCoroutine
val probeCompletion = probeCoroutineCreated(completion)
//This就是这个suspend lambda。在Demo中就是myCoroutineFun。疑问我们的lambda为什么是这个BaseContinuationImpl对象
return if (this is BaseContinuationImpl)
create(probeCompletion)
else
//else分支在我们demo中不会走到
createCoroutineFromSuspendFunction(probeCompletion) {
(this as Function1<Continuation<T>, Any?>).invoke(it)
}
}
重点代码:(this is BaseContinuationImpl)
我们的this
是myCoroutineFun
对象。为什么这里会可以判断为BaseContinuationImpl
对象?
val myCoroutineFun: suspend () -> String = {
logD("返回 hello结果")
mySuspendFun()
}
这这里就是编译器的黑魔法体现的地方。
我们的testOne
函数所在类com.example.studycoroutine.chapter.two.CoroutineRun.kt
反编译看看吧。
原始代码:
package com.example.studycoroutine.chapter.two
suspend fun suspendFunHaveOneParameter(msg: String): String {
return "incoming parameter [$msg]";
}
suspend fun mySuspendFun(): String {
return "hello";
}
fun testOne(){
val myCoroutineFun: suspend () -> String = {
logD("返回 hello结果")
mySuspendFun()
}
val myCoroutine = MyCoroutine()
//这种写法是下面的封装而已
//myCoroutineFun.startCoroutine(myCoroutine)
val createCoroutine = myCoroutineFun.createCoroutineUnintercepted(myCoroutine)
createCoroutine.resume(Unit)
}
反编译后包结构图:
我们我知道lambda
表达式会在编译后转化一个对应类,myCoroutineFun
将转化为上诉的图中
的myCorotineFun$1
类
val myCoroutineFun: suspend () -> String = {
logD("返回 hello结果")
mySuspendFun()
}
来看看编译后的样子
//CoroutineRunKt$testOne$myCorotineFun$1.java
static final class CoroutineRunKt.testOne.myCoroutineFun.1 extends SuspendLambda implements Function1 {
int label;
CoroutineRunKt.testOne.myCoroutineFun.1(Continuation arg2) {
super(1, arg2);
}
//创建对象实例传入的参数实例就是我们的myCoroutine
public final Continuation create(Continuation arg2) {
Intrinsics.checkParameterIsNotNull(((Object)arg2), "completion");
return new CoroutineRunKt.testOne.myCoroutineFun.1(arg2);
}
public final Object invoke(Object arg2) {
return ((CoroutineRunKt.testOne.myCoroutineFun.1)this.create(((Continuation)arg2))).invokeSuspend(Unit.INSTANCE);
}
//状态机本文先不做分析。后续文章重点分析所谓的状态迁移
public final Object invokeSuspend(Object $result) {
Object v0 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
int v1 = this.label;
if(v1 == 0) {
ResultKt.throwOnFailure($result);
LogKt.logD("返回 hello结果");
this.label = 1;
v1_1 = CoroutineRunKt.mySuspendFun(((Continuation)this));
if(v1_1 == v0) {
return v0;
}
}
else {
if(v1 == 1) {
ResultKt.throwOnFailure($result);
return $result;
}
throw new IllegalStateException("call to \'resume\' before \'invoke\' with coroutine");
}
return v1_1;
}
}
编译后的lambda
继承自SuspendLambda
,而SuspendLambda
继承链为:ContinuationImpl
->BaseContinuationImpl
->BaseContinuationImpl
在这里一切都释然了Continuation
的创建和suspend
函数的调用关系。
再回过头看看下面的代码也就没什么了
//kotlin.coroutines.intrinsics.IntrinsicsKt.class
@SinceKotlin("1.3")
public actual fun <T> (suspend () -> T).createCoroutineUnintercepted(
completion: Continuation<T>
): Continuation<Unit> {
//probeCompletion 还是我们传入completion对象,在我们的Demo就是myCoroutine
val probeCompletion = probeCoroutineCreated(completion)
//This就是这个suspend lambda。在Demo中就是myCoroutineFun。疑问我们的lambda为什么是这个BaseContinuationImpl对象
return if (this is BaseContinuationImpl)
create(probeCompletion)
else
//else分支在我们demo中不会走到
createCoroutineFromSuspendFunction(probeCompletion) {
(this as Function1<Continuation<T>, Any?>).invoke(it)
}
}
还没有评论,来说两句吧...