一.Kotlin 协程启动方式总结
1.withContext 同步串行 带返回
2.launch 异步 不带返回
3.asyc 异步 带返回
4.runblocking 同步 带返回
二.作用域函数 ,T的扩展函数 (with不是T的扩展函数)都是内联函数
Kotlin中的lateinit和by lazy有以下几个区别:
by lazy { … } 只能被用在被val修饰的变量上,而lateinit只能被用var修饰的变量上。
lateinit 不能用在可空的属性上和Java的基本类型上,但 by lazy { … } 可以。
lateinit 可以在任何位置初始化并且可以初始化多次,而 by lazy { … } 在第一次被调用时就被初始化,想要被改变只能重新定义。
lateinit 有支持(反向)域(Backing Fields),但 by lazy { … } 没有。
三.协程作用域 :
1.顶级作用域
在 Android 中,某些 KTX 库为某些生命周期类提供自己的 CoroutineScope。主要有以下4种:
GlobeScope:全局范围,不会自动结束执行。
MainScope:主线程的作用域,全局范围
lifecycleScope:生命周期范围,用于activity等有生命周期的组件,在Desroyed的时候会自动结束。
viewModeScope:ViewModel范围,用于ViewModel中,在ViewModel被回收时会自动结束
所有的Scope都是 CoroutineScope 的子类。以上4种可以认为是最顶级的协程作用域,能在Activity、Fragment、ViewModel等类的 普通函数中 直接调用
2. coroutineScope & 3.supervisorScope
这两个就是2个挂起函数,分别表示协同作用域和主从作用域,因为是挂起函数所以也必须在协程块或挂起函数内调用:
private fun request() {
lifecycleScope.launch {
coroutineScope { // 协同作用域,抛出未捕获异常时会取消父协程
launch { }
}
supervisorScope { // 主从作用域,抛出未捕获异常时不会取消父协程
launch { }
}
}
}
二者的区别:
supervisorScope 表示主从作用域,会继承父协程的上下文,它的特点就是子协程的异常不会影响父协程,内部的 子协程挂掉 不会影响外部的父协程和兄弟协程的继续运行,它就像一道防火墙,隔离了异常,保证程序健壮,但是如果外部协程挂掉还是可以取消子协程的,即 单向传播。它的设计应用场景多用于 子协程为独立对等的任务实体的时候,比如一个下载器,每一个子协程都是一个下载任务,当一个下载任务异常时,它不应该影响其他的下载任务。
coroutineScope 表示 协同作用域, 内部的协程 出现异常 会向外部传播,子协程未捕获的异常会向上传递给父协程, 子协程 可以挂掉外部协程 , 外部协程挂掉也会挂掉子协程,即 双向传播 。 任何一个子协程异常退出,会导致整体的退出。