现在Android开发中运用异步一般都用上协程了,可是咱们怎么处理协程中的反常呢?

在谈协程处理反常方法之前,咱们先来说下协程中产生反常后会呈现什么状况.

当协程产生反常后

这儿分为两种

1,运用的协程Context是Job.

默许状况下创立协程Scope中的Context便是Job,

总结下如何处理Android协程的异常

这种状况下一个Scope中的某个协程产生反常,这个Scope中的一切Child都会撤销,而且反常会向上传递。假如不希望某个子协程产生反常一切的协程都撤销的话就要用到SupervisorJob

2,运用的协程Context是SupervisorJob.

假如咱们创立CoroutineScope运用CoroutineScope(SupervisorJob()),那么它的子协程产生反常对别协程是没有影响的.

怎么处理协程的反常

发动协程有两种方法,一种launch另外一种的async. 这两种发动方法处理反常是有差异的。

运用try catch

当咱们运用launch创立协程的时分可以直接运用try catch去捕获反常

scope.launch {
    try {  
        codeThatCanThrowExceptions()  
    } catch(e: Exception) {  
        // Handle exception  
    }  
}

运用async的时分,try catch需求放在发动的时分调用(这儿调用await代表开始答应协程)

supervisorScope {
    val deferred = async {
        codeThatCanThrowExceptions()
    }    try {
        deferred.await()
    } catch(e: Exception) {
        // 在这儿处理反常
    }
}

留意这儿运用了supervisorScope,假如咱们运用coroutineScope,状况会有些不同

coroutineScope {
    try {
        val deferred = async {
            codeThatCanThrowExceptions()
        }
        deferred.await()
    } catch(e: Exception) {
        // 这儿不会捕获反常,会传递反常到scope
    }
}

至于这种状况咱们需求处理coroutineScope抛出的反常就要用到CoroutineExceptionHandler了.

运用CoroutineExceptionHandler

CoroutineExceptionHandler也是属于Coroutine Context中的一个元素,用于处理协程中抛出的未处理反常.

val handler = CoroutineExceptionHandler {
    context, exception -> println("Caught $exception")
}

举个比如怎么运用它

val scope = CoroutineScope(Job())
scope.launch(handler) {
    launch {
        throw Exception("Failed coroutine")
    }
}

留意CoroutineExceptionHandler必须要放在正确的方位才干捕获反常,例如放在如下的方位是不能捕获住反常的.

val scope = CoroutineScope(Job())
scope.launch {
    launch(handler) {
        throw Exception("Failed coroutine")
    }
}

由于之前说到运用CoroutineScope中的反常是具有向上传递的. 除非咱们这儿换成SupervisorJob。

val scope = SupervisorJob(Job())
scope.launch {
    launch(handler) {
        throw Exception("Failed coroutine")
    }
}

总结

一般咱们之前写程序过程中都是在运用try catch在捕获反常,可是当咱们运用协程后状况就有些不同,咱们要考虑反常的传递性,还需求考虑是否需求运用CoroutineExceptionHandler大局捕获协程中的反常