SupervisorJob和supervisorScope的区别
SupervisorJob只能表示当前级别的错误拦截,其中子job还是不会被拦截
val c =
CoroutineExceptionHandler { coroutineContext: CoroutineContext, throwable: Throwable ->
Log.e("123","${throwable.message}")
}
val sc = CoroutineScope(supervisorJob)
sc.launch(c) {
delay(1000)
Log.e("123","task1")
throw Throwable("baocuo")
}
sc.launch(c){
delay(2000)
Log.e("123","task2")
}
结果:
//task1
//baocuo
//task2
可见sc层级的兄弟job都互不影响
但是如果代码如下
sc.launch(c) {
launch {
delay(1000)
Log.e("123","task1")
throw Throwable("baocuo")
}
launch {
delay(2000)
Log.e("123","task2")
}
}
结果:
//task1
//baocuo
task1报错,task2也被取消了
sc.launch(c) {
launch {
delay(500)
Log.e("123","task")
throw Throwable("baocuo111")
}
delay(1000)
Log.e("123","task1")
throw Throwable("baocuo")
}
sc.launch(c){
delay(2000)
Log.e("123","task2")
}
结果:
2023-10-25 00:13:17.404 16453-16496 E task
2023-10-25 00:13:17.412 16453-16496 E baocuo111
2023-10-25 00:13:18.898 16453-16496 E task2
结果正确
sc.launch(c) {
supervisorScope {
launch {
delay(1000)
Log.e("123","task1")
throw Throwable("baocuo")
}
launch {
delay(2000)
Log.e("123","task2")
}
}
}
supervisorScope 表示下面的launch都是supervisorJob,所以task1和task2互不影响
supervisorJob只是对原job进行了一次包装,详情请看 kotlinx.coroutines.JobSupport里面childCancelled 和notifyCancelling的实现