关于try catch和CoroutineExceptionHandler的问题

来源:7-8 协程的异常处理2

慕UI8482615

2019-08-05

这是我的一段代码,已经在顶级try catch了,程序还是崩了,感觉捕获不了异常:

mBtn.setOnClickListener {
            try {
                GlobalScope.launch {
		            // 或者try catch 这个范围
                    val job = GlobalScope.launch {
                        launch {
                            throw NullPointerException()
                        }
                    }
                    job.join()
                }
            } catch (e: Exception) {
                Log.e(TAG, e.message + " --- ")
            }
}

反而用CoroutineExceptionHandler就可以捕获异常:

mBtn.setOnClickListener {
                GlobalScope.launch {
                    val job = GlobalScope.launch(CoroutineExceptionHandler { coroutineContext, throwable ->
		                Log.e(TAG, throwable.message)
	            }) {
                        launch {
                            throw NullPointerException()
                        }
                    }
                    job.join()
                }       
}

我没看错的话老师你《7-6 协程的异常处理1》的18:14秒运行完的结果也是崩了的,用的也是try catch,老师能解释一下这是什么情况么?为什么用try catch还是会崩,CoroutineExceptionHandler就不会崩

写回答

1回答

bennyhuo

2019-08-05

其实视频也有提到,CancelableExceptIon是一个有特定含义的异常,协程用他来表示被取消,而不是一个真正意义上的异常,因此ExceptionHandler不去捕获这个异常。而try catch 是java本身的异常机制,他并不在乎是什么异常,因此捕获的时候也可以捕获到取消异常了。

0
2
bennyhuo
因为里面网络出了异常,所以异常会向上抛,这时候try catch 这个join是不能捕获#2里面的网络异常,这很容易理解其实,因为你没有直接在网络请求那句捕获。 那么为什么try catch那句居然发现有个取消异常呢?因为子协程出了异常,会把父协程也取消掉,也就是父协程里面的代码如果继续执行实际上是违反规定的,因此join后面的逻辑就不应该执行了,应该取消,在实现协程的时候,为了做到让join后面的代码不执行,协程在挂起函数也就是这里的join处抛了取消异常,但取消异常并不是真正的异常,只是为了不让协程继续执行而已。注意你真正的异常是网络异常。
2019-08-06
共2条回复

Android首选开发语言Kotlin入门与进阶

Google I/O大会钦定Android一级开发语言,现在不学,等待何时

3122 学习 · 387 问题

查看课程