Kotlin:协程到底是什么何方神圣?

共 1936字,需浏览 4分钟

 ·

2021-02-04 08:29

前言

本文将带你快速了解近期非常热门的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名
  • 参与方式:「点击文章右下角”在看“ -> 回复截图到公众号 即可,我将从中随机抽取」

    点击“在看”就能升职 & 加薪水哦!
浏览 33
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐