kotlin协程异常处理之-CoroutineExceptionHandler
目录:
CoroutineExceptionHandler用于在协程中捕获异常。
一、CoroutineExceptionHandler只能处理当前域内开启的子协程或者当前协程抛出的异常
GlobalScope.launch(CoroutineExceptionHandler { _, throwable -> Log.d("MainActivity_", throwable.message.toString()) }) { launch { Log.d("MainActivity_", "launch-> threadName->" + Thread.currentThread().name) throw NullPointerException() } }
不会发生崩溃。
GlobalScope.launch(CoroutineExceptionHandler { _, throwable -> Log.d("MainActivity_", throwable.message.toString()) }) { GlobalScope.launch { Log.d("MainActivity_", "launch-> threadName->" + Thread.currentThread().name) throw NullPointerException() } }
而这个例子便发生崩溃了。
二、CoroutineExceptionHandler 仅在未捕获的异常上调用,也即这个异常没有任何方式处理时(比如在源头tryCatch了)
GlobalScope.launch(CoroutineExceptionHandler { _, throwable -> Log.d("MainActivity_", throwable.message.toString()) }) { launch { try { Log.d("MainActivity_", "launch-> threadName->" + Thread.currentThread().name) throw NullPointerException() } catch (e: Exception) { Log.d("MainActivity_", "catch->" + e.message) e.printStackTrace() } } }
输出:
D/MainActivity_: launch-> threadName->DefaultDispatcher-worker-2 D/MainActivity_: catch->null
可以看出发生异常的时候被捕获了,CoroutineExceptionHandler里面的回调方法不会执行。
三、当子协程发生异常时,它会优先将异常委托给父协程区处理,以此类推 直到根协程作用域或者顶级协程 。因此其永远不会使用我们子协程 CoroutineContext 传递的 CoroutineExceptionHandler(SupervisorJob 除外)。
val scope = CoroutineScope(Job()) scope.launch { launch(CoroutineExceptionHandler { _, _ -> }) { delay(10) throw RuntimeException() } }
发生崩溃。