kotlin: 不要用 try-catch 直接包裹 launch、async
一,例子一
代码:
//处理按钮点击事件
binding.button1.setOnClickListener {
runBlocking {
try {
launch {
delay(100L)
1 / 0 // 故意制造异常
}
} catch (e: ArithmeticException) {
println("Catch: $e")
}
delay(500L)
println("End")
}
}
运行结果:崩溃,未捕捉到异常
二,例子二
代码:
//处理按钮点击事件
binding.button2.setOnClickListener {
runBlocking {
var deferred: Deferred<Unit>? = null
try {
deferred = async {
delay(100L)
1 / 0
}
} catch (e: ArithmeticException) {
println("Catch: $e")
}
deferred?.await()
delay(500L)
println("End")
}
}
运行结果:崩溃,未捕捉到异常
三,改进,针对launch
捕捉不到异常的原因:
当协程体当中的“1/0”执行的时候,我们的程序已经跳出 try-catch 的作用域了
代码:
//处理按钮点击事件
binding.button3.setOnClickListener {
runBlocking {
launch {
try {
delay(100L)
1 / 0 // 故意制造异常
} catch (e: ArithmeticException) {
println("Catch: $e")
}
}
delay(500L)
println("End")
}
}
说明:解决方法就是:
我们把 try-catch 挪到 launch{} 协程体内部。
这样一来,它就可以正常捕获到 ArithmeticException 这个异常了
运行结果:
四,改进:针对async
代码:
//处理按钮点击事件
binding.button4.setOnClickListener {
runBlocking {
var deferred: Deferred<Unit>? = null
deferred = async {
try {
delay(100L)
1 / 0
} catch (e: ArithmeticException) {
println("Catch: $e")
}
}
deferred?.await()
delay(500L)
println("End")
}
}
说明:
把 try-catch 挪到了 async{} 协程体内部,
这样可以正常捕获到 ArithmeticException 这个异常
运行结果: