在 Kotlin 协程里,异常处理器(CoroutineExceptionHandler
)和 try-catch
块在处理异常时各有特点,它们之间存在一定的包含关系,下面详细介绍:
try-catch
块在协程内部使用 try-catch
块可以捕获并处理局部异常。它的作用范围仅限于所在的协程体,仅能捕获该协程体中抛出的异常。
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
try {
throw RuntimeException("Exception in coroutine")
} catch (e: RuntimeException) {
println("Caught exception in try-catch: ${e.message}")
}
}
job.join()
}
在这个例子中,try-catch
块捕获了协程体中抛出的 RuntimeException
,并进行了处理。
CoroutineExceptionHandler
)CoroutineExceptionHandler
是一个用于全局处理未捕获异常的处理器。它可以在协程作用域或者协程构建器中设置,当协程中抛出未被 try-catch
捕获的异常时,会触发异常处理器。
import kotlinx.coroutines.*
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught exception in CoroutineExceptionHandler: ${exception.message}")
}
val job = GlobalScope.launch(handler) {
throw RuntimeException("Exception in coroutine")
}
job.join()
}
在这个例子中,由于协程体中没有使用 try-catch
块捕获异常,所以异常被 CoroutineExceptionHandler
捕获并处理。
try-catch
优先处理:当协程中抛出异常时,try-catch
块会首先尝试捕获并处理异常。如果异常被 try-catch
块捕获,那么异常处理器(CoroutineExceptionHandler
)将不会被触发。import kotlinx.coroutines.*
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught exception in CoroutineExceptionHandler: ${exception.message}")
}
val job = launch(handler) {
try {
throw RuntimeException("Exception in coroutine")
} catch (e: RuntimeException) {
println("Caught exception in try-catch: ${e.message}")
}
}
job.join()
}
在这个例子中,try-catch
块捕获了异常,所以 CoroutineExceptionHandler
不会被触发。
try-catch
块没有捕获到异常,那么异常会被传递给异常处理器(CoroutineExceptionHandler
)进行处理。import kotlinx.coroutines.*
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught exception in CoroutineExceptionHandler: ${exception.message}")
}
val job = launch(handler) {
throw RuntimeException("Exception in coroutine")
}
job.join()
}
在这个例子中,由于协程体中没有使用 try-catch
块捕获异常,所以异常被 CoroutineExceptionHandler
捕获并处理。
综上所述,try-catch
块用于处理协程内部的局部异常,而异常处理器(CoroutineExceptionHandler
)用于处理未被 try-catch
块捕获的全局异常。它们之间是一种互补的关系,共同保证了协程中异常的有效处理。