Coroutine 协程

一、协程概念

协程是一种并发设计模式,用它来简化异步执行的代码
优点:

  1. 轻量:协程可以挂起,比阻塞更省内存
  2. 减少内存泄漏
  3. 支持取消
  4. 支持Jatpack集成

二、CoroutineScope 协程作用域

  1. GlobalScope 全局的,一般不会释放,所以基本不要
  2. MainScope 需要自己 取消
  3. LifecycleScope 不需要关心取消,自动绑定Lifecycle生命周期了
  4. ViewModelScope 不需要关心取消,自动绑定ViewModel生命周期了

三、CoroutineScope.launch、CoroutineScope.async

  • 不阻塞线程,在后台开启协程,默认立马执行
  • 区别:launch 返回是Job,async 返回是Deferred<T> ,可以调用await()等待获取结果

四、suspend(挂起) 函数特点

  • suspend函数,不阻塞线程
  • 必须在协程或者suspend函数里面执行
  • 要等suspend函数执行完成,代码才继续往下执行

五、suspend withContext 、suspend coroutineScope

  • 属于suspend 函数,不阻塞线程
  • 里面最后一行作为返回值,要等里面的代码执行完成,才继续往下执行
  • 区别:withContext可以设置作用域,coroutineScope不行

六、CoroutineStart - 启动模式

  1. CoroutineStart.DEFAULT: 协程创建后,立即开始调度,但 有可能在执行前被取消。在调度前如果协程被取消,其将直接进入取消响应的状态。
  2. CoroutineStart.ATOMIC : 协程创建后,立即开始调度, 协程执行到第一个挂起点之前不响应取消。其将调度和执行两个步骤合二为一,就像它的名字一样,其保证调度和执行是原子操作,因此协程也 一定会执行。
  3. CoroutineStart.LAZY : 只要协程被需要时(主动调用该协程的 start、 join、 await等函数时 ),才会开始调度,如果调度前就被取消,协程将直接进入异常结束状态。
  4. CoroutineStart.UNDISPATCHED : 协程创建后,立即在当前线程中执行,直到遇到第一个真正挂起的点。 是立即执行,因此协程 一定会执行

六、Dispatchers - 协程调度器

  1. Default: 默认调度器 ,适合处理后台计算,其是一个 CPU 密集型任务调度器
  2. IO: IO 调度器,适合执行 IO 相关操作,其是 IO 密集型任务调度器
  3. Main: UI 调度器,根据平台不同会被初始化为对应的 UI 线程的调度器, 例如在Android 平台上它会将协程调度到 UI 事件循环中执行,即通常在 主线程上执行
  4. Unconfined:“无所谓“调度器,不要求协程执行在特定线程上。协程的调度器如果是 Unconfined, 那么它在挂起点恢复执行时会在恢复所在的线程上直接执行,当然, 如果嵌套创建以它为调度器的协程,那么这些协程会在启动时被调度到协程框架内部的事件循环上,以避免出现 StackOverflow。
七、协程使用
// 协程测试类
object CoroutineTest : CoroutineScope by MainScope() { // 代理类实现 协程作用域
    // 协程测试
    suspend fun coroutineTest() {

        // 挂起函数,要等代码执行完,才往下执行
        val job = launch(Dispatchers.IO, CoroutineStart.LAZY) {

            // GlobalScope 顶级作用域 其它作用域取消,对其没有影响
            GlobalScope.launch {
                // ...
                delay(1000)
            }

            val deferred = async(Dispatchers.IO) {
                "async result"
            }
            // withContext 挂起方法要在 协程 或者 suspend方法 里面调用 
            val withContextRes = withContext(Dispatchers.Default) {
                // ... 
                "withContext result"
            }

            // await 挂起方法 要在 协程 或者 suspend方法 里面调用 
            val asyncRes = deferred.await() // 挂起 获取结果
        }
        // CoroutineStart.LAZY 要调用 start 或者 await()方法后才执行
        job.start()
        // 取消并等待执行完成
        job.cancelAndJoin()
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容