## 协程的取消需要内部配合
单纯的执行`job.cancel()`是无法取消当前执行的协程,就像无法取消正在执行过程中的线程;
```kotlin
fun main() = runBlocking {
val job = launch(Dispatchers.Default) {
var i = 0
// 变化在这里,只有协程处于活跃状态的时候,才会继续执行循环内部的代码
while (isActive) {
Thread.sleep(500L)
i++
println("i = $i")
}
}
delay(2000L)
job.cancel()
job.join()
println("End")
}
```
## 不要轻易打破协程的父子结构
下面代码中`firstJob`无法通过`parentJob.cancel`被取消,因为`firstJob`设置了自己的`Job()`对象,并没有关联`parentJob`,打破了其协程的父子结构;
```kotlin
fun main2() = runBlocking {
val parentJob = launch(Dispatchers.IO) {
val firstJob = launch(Job()) {
var i = 0
while (isActive) {
Thread.sleep(500L)
i++
println("First i = ${i}")
}
}
val secondJob = launch {
var i = 0
while (isActive) {
Thread.sleep(500L)
i++
println("Second i = ${i}")
}
}
}
delay(2000L)
parentJob.cancel()
parentJob.join()
println("End")
Thread.sleep(100_000)
}
```
## 捕获CancellationException以后,要考虑是否应该重新抛出来
```kotlin
fun main() = runBlocking {
val parentJob = launch(Dispatchers.IO) {
launch() {
var i = 0
while (true) {
try {
delay(500L)
} catch (e: CancellationException) {
// 这里如果不将CancellationException抛出,那么该协程被取消也不会结束
e.printStackTrace()
}
i++
println("First i = ${i}")
}
}
launch {
var i = 0
while (true) {
delay(500L)
i++
println("Second i = ${i}")
}
}
}
delay(2000L)
parentJob.cancel()
parentJob.join()
println("End")
Thread.sleep(100_000)
}
```
## 不要直接使用try-catch直接包裹launch、async
使用`launch`和`async`启动的协程其实已经是一个封闭的任务,任务内部有自己的异常处理逻辑,再外部进行`try-catch`是无法得到响应的内部异常的,只能捕获到创建协程时候的异常;
## 灵活使用SupervisorJob,控制异常传播范围
`SupervisorJob`目前我只觉得只有当前协程抛出异常才能做到不影响子协程和父协程,如果是子协程抛出异常那么`SupervisorJob`也无能为力。因为创建子协程的时候又会创建一个新的`job`只不过其`parentjob`是`父协程的job`。
## 使用CoroutineExceptionHandler处理复杂结构的协程异常,它仅在顶层协程中起作用
- 写在前面的话
- Java
- 基础
- Double的比较
- 小数怎么用二进制表示
- 多线程
- 并发和并行
- 线程池
- 线程池背景
- 线程池构造
- 任务阻塞队列
- Flutter
- 基础知识
- Dart基础
- Android
- 项目架构
- View
- 非UI线程更新View
- AlarmManager
- 对比postDelaryed和Timer
- Bitmap
- 加载100M的图片却不撑爆内存
- Bitmap压缩
- Bitmap局部解码
- 计算图片的内存占用
- Android动画
- Android动画类型
- Android动画原理
- 属性动画
- 帧动画
- 补间动画
- 使用动画的注意事项
- Android新特性
- 权限组
- Android23(Marshmallow)-6.0
- Android24(Nougat)-7.0
- Android26(Oreo)-8.0
- Android28(Pie)-9.0
- Android29(Q)-10.0
- AndroidX迁移
- Kotlin
- 关键字
- Kotlin操作符
- CoroutineScope
- Flow
- CoroutineException