我有一个问题:当我的代码在协程fn中(在后台服务中)引发多个异常时,则主应用程序会在后台服务中执行catch块之前崩溃,但之后执行catch块。 我该如何解决?
如果抛出1错误,代码可以正常工作,但是如果抛出多个错误,则代码将崩溃。
期望:捕获第一个错误并在runBlocking中停止执行,而不会导致主应用程序崩溃。
错误信息:
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-8
Process: ..., PID: 9260
RuntimeException: my error
at MyBackgroundService ...
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:234)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)
以下代码是我的代码的非常简化的版本,代表了结构化并发的外观:
class MyBackgroundService : IntentService("..."), CoroutineScope {
private var cJob: Job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + cJob
override fun onHandleIntent(intent: Intent?) {
/*...*/
try {
runBlocking {
fn1();
fn2();
}
} catch(e: RuntimeException) {
//before execution reach this the main app crashed with my custom error
//after that the app execute the catch block code and other coroutine fn still running in fn2
}
}
private suspend fun fn1() {
withContext(coroutineContext) {
/*...*/
}
}
private suspend fun fn2() {
withContext(coroutineContext) {
/*...*/
fn3()
/*other similar fn calls*/
/*after throw exception in fn3 the other coroutine functions still running */
}
}
private suspend fun fn3() {
launch {
fn4()
}
}
private suspend fun fn4() {
coroutineScope {
launch {
/*...*/
fn5()
}
}
}
fun CoroutineScope.fn5() {
for (/*...*/) {
launch {
fn6()
}
}
}
private suspend fun fn6() {
coroutineScope {
launch {
/*...*/
if (/*..*/) {
throw RuntimeException("my error") //this called multiple time because of for
}
}
}
}
}
最佳答案
好的,我发现了问题:
fn3中存在歧义的协程上下文,因此可解决:
private suspend fun fn3() {
coroutineScope {
launch {
fn4()
}
}
}
关于android - Kotlin协程-多个错误导致到达catch block 之前崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60502708/