Kotlin:协程到底是什么何方神圣?
前言
本文将带你快速了解近期非常热门的Kotlin协程相关内容。
定义
协程是一种「并发设计模式」。
作用
在 Android 平台上使用它来简化异步执行的代码。
意义
剔除了我们传统的Callback回调方式,将异步编程向同步对齐,通过替代回调(callback)来简化异步代码。
优点
轻量:可在单个线程上运行多个协程,因为协程支持挂起,不会使正在运行协程的线程阻塞。挂起比阻塞节省内存,且支持多个并行操作; 内存泄露更少:使用结构化并发机制在一个作用域内执行多个操作; 内置取消支持:取消功能会自动通过正在运行的协程层次结构传播; Jetpack集成:许多 Jetpack 库都包含提供全面协程支持的扩展。某些库还提供自己的协程作用域,可供您用于结构化并发。
核心关键字:Suspend
每一个被suspend修饰的方法都必须在另一个suspend函数 / Coroutine协程程序中进行调用。
每一个suspend修饰的方法 / lambda表达式都会在代码调用的时候为其额外添加Continuation类型的参数。这里涉及到一种机制俗称CPS(Continuation-Passing-Style)。具体示例如下:
// 转换前
@GET("/v2/news")
suspend fun newsGet(@QueryMap params: Map): NewsResponse
// 转换后
@GET("/v2/news")
fun newsGet(@QueryMap params: Map, c: Continuation): Any?
经过转换之后,原有的返回类型NewsResponse被添加到新增的Continutation参数中,同时返回了Any?类型:在Kotlin中比较特殊,它可以代表任意类型。
当suspend函数被协程挂起时,它会返回一个特殊的标识COROUTINE_SUSPENDED,而它本质就是一个Any;当协程不挂起进行执行时,它将返回执行的结果或者引发的异常。这样为了让这两种情况的返回都支持,所以使用了Kotlin独有的Any?类型。
下面简单说下Continutation参数:
// 首先来看下Continutation的源码
public interface Continuation<in T> {
/**
* The context of the coroutine that corresponds to this continuation.
*/
public val context: CoroutineContext
/**
* Resumes the execution of the corresponding coroutine passing a successful or failed [result] as the
* return value of the last suspension point.
*/
public fun resumeWith(result: Result)
}
此处主要关注resumeWith():「用于唤醒挂起的协程」。协程在执行的过程中,为了防止阻塞使用了挂起的特性,一旦协程内部的逻辑执行完毕之后,就是通过该方法来唤起协程,让它在之前挂起的位置继续执行下去。
所以每一个被suspend修饰的函数都会获取上层的Continutation,并将其作为参数传递给自己。Continutation是上层传递过来的,与协程创建的时候(launch的时候)一起被创建 & 启动了协程,所以在它里面进行挂起的协程传递的参数都是这个对象。
GlobalScope.launch {
// ...
}
总结
协程使用resumeWith替换传统的回调(callback); 每一个协程的创建都会伴随Continutation的存在 & 自动回调一次Continutation的resumeWith(),从而启动协程。
「Carson每天带你学习一个Android知识点」,长按扫描关注公众号,我们明天见哦!
最后福利:学习资料赠送

福利:由本人亲自撰写 & 整理的「Android学习方法资料」 数量:10名 参与方式:「点击文章右下角”在看“ -> 回复截图到公众号 即可,我将从中随机抽取」 点击“在看”就能升职 & 加薪水哦!