请教个问题 createCoroutineUnintercepted
来源:12-2 案例:仿官方框架实现 launch 2

xxxxjase普通
2020-10-06
//kotlinx.coroutines.Builders.common.kt
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
val newContext = newCoroutineContext(context)
val coroutine = if (start.isLazy) // 这里创建了协程
LazyStandaloneCoroutine(newContext, block) else
StandaloneCoroutine(newContext, active = true)
coroutine.start(start, coroutine, block)
return coroutine
}
上面的已经创建了协程了,但是在 coroutine.start 里面,我一路跟到 CoroutineStart 中:
/**
* Starts the corresponding block as a coroutine with this coroutine's start strategy.
*
* * [DEFAULT] uses [startCoroutineCancellable].
* * [ATOMIC] uses [startCoroutine].
* * [UNDISPATCHED] uses [startCoroutineUndispatched].
* * [LAZY] does nothing.
*
* @suppress **This an internal API and should not be used from general code.**
*/
@InternalCoroutinesApi
public operator fun <T> invoke(block: suspend () -> T, completion: Continuation<T>) =
when (this) {
CoroutineStart.DEFAULT -> block.startCoroutineCancellable(completion)
CoroutineStart.ATOMIC -> block.startCoroutine(completion) // 进入这里
CoroutineStart.UNDISPATCHED -> block.startCoroutineUndispatched(completion)
CoroutineStart.LAZY -> Unit // will start lazily
}
然后进入 block.startCoroutine:
/**
* Starts a coroutine without a receiver and with result type [T].
* This function creates and starts a new, fresh instance of suspendable computation every time it is invoked.
* The [completion] continuation is invoked when the coroutine completes with a result or an exception.
*/
@SinceKotlin("1.3")
@Suppress("UNCHECKED_CAST")
public fun <T> (suspend () -> T).startCoroutine(completion: Continuation<T>) {
createCoroutineUnintercepted(completion).intercepted().resume(Unit)
}
这里的 createCoroutineUnintercepted 又是在创建协程,completion 实际上就是上面 launch 中创建的协程了。
1、这个 createCoroutineUnintercepted 为啥又创建一边??
2、createCoroutineUnintercepted 的源码在哪里?
4回答
-
xxxxjase普通
提问者
2020-10-07
下面是一个 launch 中创建的协程:
val coroutine = if (start.isLazy) // 这里创建了协程
LazyStandaloneCoroutine(newContext, block) else
StandaloneCoroutine(newContext, active = true) 里面创建的协程也是一个 Continuation 对象suspend lambda 通过编译器处理后,会生成一个 SuspendLambda 类
继承关系如下:SuspendLambda -> ContinuationImpl -> BaseContinuationImpl : Continuation<Any?>
可以看到,还是一个 Continuation 对象;
然后会将上面的 Continuation 对象作为构造器的参数,然后创建 suspend lambda 对应的。
我的理解是下面的这个 Continuation 是 launch 中的那个 Continuation 的包装了一层;
012020-10-07 -
xxxxjase普通
提问者
2020-10-06
CoroutineScope.launch 方法里面已经创建了协程:Coroutine
val coroutine = if (start.isLazy) // 这里创建了协程
LazyStandaloneCoroutine(newContext, block) else
StandaloneCoroutine(newContext, active = true)那为啥还要 createCoroutineUnintercepted?? 这两个是什么关系呢??不得骑姐。。
042020-10-06 -
bennyhuo
2020-10-06
更正:
回复里面同学在 Jvm 里面找到了这个函数的实现。我确认了一下哈,后来的 Kotlin 标准库的源码有些变化,createCoroutineUnintercepted 函数现在提供了实现,不过常规的情况下还是会走到下面的 create 函数调用,这个函数仍然是需要编译器通过传入的 Lambda 表达式来生成的哈。
Kotlin 协程这几年的源码变动确实比较大,类似的还有最早的时候 Continuation 的 resume和 resumeWithException 还是它的函数,后来就成了扩展函数等等。大家在学习时,以源码为准~
---
createCoroutineUnintercepted 这个函数的源码是没有的,编译器编译时会生成一些字节码,也就是编译器会基于参数lambda表达式生成一个SuspendLambda的类,这个点咱们视频里面有提到哈。
072020-10-13 -
bennyhuo
2020-10-06
这是官方的源码哈。
createCoroutineUnintercepted 是创建协程最终要调用到的代码,所有创建协程的api其实都是对它的封装。00
相似问题