课程名称: 一课掌握Kotlin 突破开发语言瓶颈
课程章节: 协程初步 - Kotlin协程的基本要素(11-5,11-6)
课程讲师: bennyhuo
课程内容:
suspend fun foo() {} ---- suspend () -> Unit suspend fun foo(a: Int): String {} ---- suspend (Int) -> String
跟函数类型一致,只是前面多了个suspend关键字修饰
suspend修饰的挂起方法,通过Java反编译或者在Java上调用时,挂起函数会多了一个参数Continuation
fun foo(continuation: Continuation<Unit>): Any {} fun foo(a: Int, continuation: Continuation<String>): Any {}
真正的挂起就是必须异步调用resume
比如:
没有真正的挂起就是在suspendCoroutine中直接return,或者没有进行线程切换就执行resume
createCoroutine是先创建出一个协程Continuation,然后在通过Continuation.resume启动协程
fun <T> (suspend () -> T).createCoroutine( completion: Continuation<T> ): Continuation<Unit> fun <R, T> (suspend R.() -> T).createCoroutine( receiver: R, completion: Continuation<T> ): Continuation<Unit>
创建协程涉及到两个Continuation:
调用resume(Unit)
suspend { ... }.createCoroutine(object: Continuation<Unit> { override val context = EmptyCoroutineContext override fun resumeWith(result: Result<Unit>) { log("Coroutine End with $result") } }).resume(Unit)
startCoroutine是创建出协程后立马调用
fun <T> (suspend () -> T).startCoroutine( completion: Continuation<T> ) fun <R, T> (suspend R.() -> T).startCoroutine( receiver: R, completion: Continuation<T> )
suspend { ... }.startCoroutine(object: Continuation<Unit> { override val context = EmptyCoroutineContext override fun resumeWith(result: Result<Unit>) { log("Coroutine End with $result") } })
suspend { ... }.startCoroutine(object: Continuation<Unit> { override val context = EmptyCoroutineContext ... })
interface ContinuationInterceptor: CoroutineContext.Element { fun <T> interceptContinuation( continuation: Continuation<T> ): Continuation<T> }
suspend { ... }.startCoroutine(object: Continuation<Unit> { override val context = EmptyCoroutineContext override fun resumeWith(result: Result<Unit>) { ... } })
通过createCoroutine或startCoroutine创建出来的类为SuspendLambda,它是Continuation的一个实现类
其中,suspend {…}为协程的本体,是协程真正的实现逻辑
如果SuspendLambda里面有挂起函数的调用,每次调用还会用SafeContinuation对SuspendLambda进行包装
SafeContinuation的作用是:
SafeContinuation可以理解为一个拦截器,它拦截的就是SuspendLambda
在前面的基础上再加上拦截器
Beny老师的讲解非常细致,对协程设计到的要素都有细致的讲解。通过介绍如何将回调改写成挂起函数,是我对挂起函数的本质有更深刻的理解。在基本要素讲解的过程中,也让我对协程的原理有了一定的认识。
由于刚刚接触协程,刚听完还是有些似懂非懂,通过手记的整理,让我对基本要素有了更深刻的认识,后续还得多回顾几遍,争取把协程摸透。