day3 让我看看,什麽是Coroutine Scope

我想大家看到前一天的范例,应该会有这种感觉吧

唉呦,很猛嘛~
[coroutine]对呀,我超厉害的啦
这code的简洁度,很勇喔!!
听话,让我看看
[coroutine]你在干嘛,不要啦
meme

特此声明,本系列文章没有任何coroutine遭到迫害

正文开始

一个完整的Coroutine Scope是由下列几个东西组成

coroutine context

  1. Job-负责控制管理一个coroutine的生命周期
  2. CoroutineDispatcher-负责控制thread之间的切换
  3. CoroutineName-你给这个coroutine取的名字,经常会在debug的时候用到
  4. CoroutineExceptionHandler- 处理在coroutine里面发生的Exception

而他们在CoroutineScope的建构式里,可以透过+声明建构参数,这边建构参数中Dispatcher和Name有默认值,CoroutineExceptionHandler则没有,Job()就得看你是实现哪种Scope,以CoroutineScope来说,需要一个Job()

CoroutineScope(Job() + Dispatchers.IO)
// or
val scope = CoroutineScope(Job())
val job = scope.launch{
    
}

...
scope.cancel()
  1. CoroutineDispatcher 默认值是 Dispatcher.Default
  2. CoroutineName 默认值是 "coroutine"

source

浅谈Job

每当我们创建一个Coroutine,他会返回一个Job,让我们可以识别并控制Coroutine的生命周期,而我们也可以自己实例一个Job,作为Coroutine context的参数传入,并透过这个Job管理coroutine

但回传的job一定不会一样,因为系统始终会分配新的job,coroutine 的父子继承关系,我明天会讲个详细,先记住就好

Parent CoroutineContext explained

https://www.kotlincn.net/docs/reference/coroutines/coroutine-context-and-dispatchers.html

浅谈Dispatcher

-IO
在主线程之外执行磁碟或网路请求,例如使用room, 从文件中读取数据或往文件写入数据,不同的网路操作等等
-Main
用於和界面交互和快速执行的工作,调用suspend方法、更新livedata对象等等
-Default
主线程之外,大量运用cpu资源运算的工作,如资料排序或解析json,DiffUtil等等
-Unconfined
不指定,通常会在当前的thread执行

更深入看dispatcher,jast带你看源码

浅谈CoroutineExceptionHandler

在coroutine,任何操作如果 throw Exception,会被交由parent coroutine,然後再交给parent coroutine的parent coroutine,直到root,细节会在之後开一篇出来

为什麽这边都用浅谈的呢?
因为我觉得很重要,但全部都在这边讲又太多了,这边就先给个概念

CoroutineScope作用

前面介绍完CoroutineScope的建构和继承,现在讲讲我们为什麽要实例他
一个CoroutineScope会持续追踪所有开发者launch或Async产生的coroutine,CoroutineScope不运行coroutine,更像是创造一个让协程运行的作用域,,而开发者需要透过launch, async去启用coroutine

那这样有甚麽好处吗?
有的,当我们针对root CoroutineScope执行scope.cancel()时,所有在他之下的Coroutine都会被取消,这是structured concurrency的特性

为了确保所有coroutine都被追踪,kotlin仅允许以coroutineScope创建coroutine,简单说的话,没有scope,你用不了coroutine

某些ktx package提供了生命周期相关的coroutineScope,像是viewModelScope或是LifeCycleScope,他们是由官方提供的特殊CoroutineScope,因为他们会跟着lifecycle自动取消,而我们同样可以创建自己的coroutineScope

val scope = CoroutineScope(Job() + Dispatchers.Main)

fun exampleMethod() {
    // Starts a new coroutine within the scope
    scope.launch {
        // New coroutine that can call suspend functions
        fetchDocs()
    }
}

fun cleanUp() {
    // Cancel the scope to cancel ongoing coroutines work
    //已取消的作用域将无法在创建协程
    scope.cancel()
}

非常重要的一点,如果你自己创建了CoroutineScope,但不去cancel掉,这个coroutine并不会被gc回收
这边说不会被回收-stackoverFlow

连结整理

必看

官方blog
文档

推荐看

jast带你看源码


<<:  [Day_4]Python 字串(1)

>>:  Day 03 : 我不要很多零钱- Coin Change

GitHub Security - 基本安全相关功能介绍

如果读者有些 CI/CD 工具使用经验,你可能会发现 GitHub 某些功能与市面上多数的产品不同。...

​ 疫情下的BCP对策

企业或机构日常管理铁三角 1. 合理化:做该做的事、花该花的钱 (1). 省小钱花大钱,乱省一通得不...

Day 5 双向绑定及回圈

今天来介绍v-model&data跟v-for的用法 data→用来储存里面的资料,当dat...

数位签章(digital signature)

-数位签章 使用您的私钥加密代码的指纹或对代码进行散列并使用您的私钥加密结果是生成数字签名的 改写...

Day29:每天一个小练习 - JS30-14-JS Reference VS Copy

参考资料: Alex老师教学 JS30-Day14-JS Reference VS Copy 传值和...