上文链接 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)
我们的thismyCoroutineFun对象。为什么这里会可以判断为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)
        }
}

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐