轉載請標明出處:https://www.cnblogs.com/tangZH/p/17307406.html - [kotlin協程小記](http://77blogs.com/?p=73 "kotlin協程小記") - [協程的async使用](http://77blogs.com/?p=77 " ...
轉載請標明出處:https://www.cnblogs.com/tangZH/p/17307406.html
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()
}
}
發生崩潰。