返回

协程入门之五:协程如何正确地传播异常?

Android





**协程中的异常传播** 

协程是一种并发编程的手段,它在 Android 开发中被广泛使用。协程可以简化异步编程,使并发编程更加方便。

协程在异常传播上与传统的 Java 代码有很大的差异。在传统的 Java 代码中,异常可以通过 `throw` 语句显式地抛出,也可以在方法签名中使用 `throws` 子句来隐式地申明方法可能抛出的异常。

在协程中,异常传播有两种不同的模型:

1. **挂起异常(Suspendable exception)** 

协程中的挂起异常是协程在挂起方法(即带 `@Suspendable` 注解的方法)中显式地抛出的异常。挂起异常可以通过 `throw` 语句显式地抛出,也可以在挂起方法的签名中使用 `@Throws` 注解来显式地申明方法可能抛出的异常。

2. **恢复异常(Exceptional result)** 

协程中的恢复异常是协程在恢复方法(即不带 `@Suspendable` 注解的方法)中隐式地传播的异常。恢复异常不能显式地抛出,而可以通过 `try-catch` 语句显式地捕获。

**协程中异常传播的最佳姿势** 

在协程中,建议使用**挂起异常** 模型来传播异常。挂起异常模型具有如下好处:

* **显式性强:**  挂起异常模型显式地申明了协程方法可能抛出的异常,这使协程的意图更加明显。
* **可追溯性好:**  挂起异常模型允许在协程中精确地追踪异常的传播路径,这有助于调试和排查问题。
* **可取消性:**  挂起异常模型允许在协程被取消时取消挂起方法,这有助于避免在协程被取消后仍然传播异常。

**如何使用挂起异常模型?** 

要使用挂起异常模型,需要遵循如下几个最佳姿势:

* **在挂起方法中显式地抛出异常:**  使用 `throw` 语句显式地抛出挂起异常。
* **在挂起方法签名中显式地申明可能抛出的异常:**  使用 `@Throws` 注解显式地申明挂起方法可能抛出的异常。
* **在恢复方法中显式地捕获异常:**  使用 `try-catch` 语句显式地捕获挂起异常。

**示例** 

下例展示了如何使用挂起异常模型:

```kotlin
// MyClass.kt
class MyClass {
  @Throws(IOException)
  fun loadFile(filePath: String): String {
    val file = File(filePath)
    val content = file.readText()
    return content
  }
}

// MainActivity.kt
class MainActivity : CompatActivity() {
  override fun