1. 区别
coroutineScope
和 supervisorScope
都是用来创建一个 CoroutineScope
并执行代码块,创建的 CoroutineScope
将继承上一级 CoroutineScope
的 CoroutineScope.coroutineContext
,但是会重写 croutineContext
的 Job
。
它们的区别在于 coroutineScope
的 coroutine
是一个 ScopeCoroutine
,而 supervisorScope
的 coroutine
是一个 SupervisorCoroutine
。SupervisorCoroutine
继承自 ScopeCoroutine
但是重写了其父类 JobSupport
的方法 childCancelled(cause: Throwable): Boolean
并返回 false
。这就是它们之间的唯一区别。
这一区别导致:
- 在
coroutineScope
中,只要任意一个子协程发生异常,整个scope
都会执行失败,并且其余的所有子协程都会被取消掉; - 在
supervisorScope
中,一个子协程的异常不会影响整个scope
的执行,也不会影响其余子协程的执行;
这两种 CoroutineScope
创建方式的区别只在于当发生异常时,它们对异常的处理方式各不相同。
我们接下来用例子详细说明它们各自如何处理异常。
2. 举例说明
若想统一处理协程的异常,防止异常引发程序崩溃,可以给协程设置 CoroutineExceptionHandler
,我们先定义一个协程异常处理器,如下,简单地把异常信息打印出来:
private val exceptionHandler = CoroutineExceptionHandler{
_, e ->
e.message?.let {
Log.e("crx", "异常信息: $it") }
}
我们在 Activity
的