Android 如何修复Kotlin JobCancellationException?
我因为Kotlin JobCancellationException而崩溃 以下是有关此次坠机的详细信息:Android 如何修复Kotlin JobCancellationException?,android,kotlin,Android,Kotlin,我因为Kotlin JobCancellationException而崩溃 以下是有关此次坠机的详细信息: kotlinx.coroutines.JobCancellationException: Job was cancelled; job=SupervisorJobImpl{Cancelling}@131dbe3 我只知道监管者JobImpl用于ViewModelScope,当ViewModel生命周期结束时,它将被称为方法cancel 我对异常非常困惑,因为Kotlin协同程序
kotlinx.coroutines.JobCancellationException: Job was cancelled; job=SupervisorJobImpl{Cancelling}@131dbe3
我只知道监管者JobImpl用于ViewModelScope,当ViewModel生命周期结束时,它将被称为方法cancel
我对异常非常困惑,因为Kotlin协同程序将忽略异常,但它被抛出并导致应用程序崩溃。如果它有堆栈,我可以算出,但它没有,只要告诉我工作被取消了
我花了大约三天多的时间来处理这个异常,但我就是不知道
我看了视频:
,我发现如果作用域被取消,并且如果您在延迟上调用wait,它将抛出异常,但我在取消的作用域上没有发现wait
那么,有人能给我看一些可能导致相同异常并导致应用程序崩溃的代码吗?Thx,在那里。最后,我找到了导致异常的原因,并且问题地址正在流动: 实际上,
awaitClose
不会抛出JobCancellationException
,因为awaitClose
是一个可取消的挂起函数。如果由于offer
不是可取消的挂起函数而取消作业,则offer
方法将抛出JobCancellationException
顺便说一句,callbackFlow
是一个实验性的API,所以它可能会导致一些错误,所以当我们使用它时,我们需要小心。因为当作业被取消时,它不会总是忽略JobCancellationException
,而且我认为它对开发人员不友好
现在我发现有两种情况会导致异常JobCancellationException
,因此我们需要尝试捕获异常
async await
,当我们调用await
方法时,我们需要尝试catch
。您可以在中找到和示例
callbackflowoffer
,当我们调用offer
方法时,我们需要尝试catch
。你可以在上面的问题中找到一个例子
我只是看到了同样的问题。该问题是由于在作业管理完成之前手动完成活动造成的
class MyApp: Application() {
override fun onCreate() {
super.onCreate()
System.setProperty(DEBUG_PROPERTY_NAME, DEBUG_PROPERTY_VALUE_ON)
}
通过这种方式,您将能够查明问题的主要原因并加以解决我知道我迟到了,但您可以在提供对象之前检查工作状态。
像这样
if(isActive) offer(Resource.success(response))
isActive是协同程序范围我和你有相同的bug。因此,我尝试编写简单的流扩展,如下所示:
fun <P> Flow<DataResult<P>>.safeStart(start: suspend FlowCollector<DataResult<P>>.() -> Unit)
: Flow<DataResult<P>> = onStart {
if (!currentCoroutineContext().isActive) return@onStart
start()
}
fun <P> Flow<DataResult<P>>.safeCatch(onCatch: suspend FlowCollector<DataResult<P>>.(cause: Throwable) -> Unit)
: Flow<DataResult<P>> = catch {
if (!currentCoroutineContext().isActive) return@catch
onCatch(it)
}
suspend inline fun <P> Flow<DataResult<P>>.safeCollect(crossinline onCollect: suspend (value: DataResult<P>) -> Unit)
: Unit = collect {
if (!currentCoroutineContext().isActive) return@collect
onCollect(it)
}
funFlow.safeStart(启动:暂停FlowCollector.(->装置)
:Flow=onStart{
如果(!currentCoroutineContext().isActive)return@onStart
开始()
}
乐趣
Flow.safeCatch(onCatch:suspendflowcollector.(原因:可丢弃)->Unit)
:流量=捕获量{
如果(!currentCoroutineContext().isActive)return@catch
onCatch(it)
}
suspend inline fun
Flow.safeCollect(交叉内联onCollect:suspend(值:DataResult
)->单位)
:单位=收集{
如果(!currentCoroutineContext().isActive)return@collect
onCollect(it)
}
您是否手动取消任何操作?您是否正在与取消的作业或范围进行交互?这里很难说问题出在哪里。我展示了所有的ViewModel#aunch方法,手动查找无处调用cancel,只在内部调用ViewModel。你能展示完整的stacktrace吗?没有stacktrace,这就是为什么我发布这个问题的原因。我希望有人能提供一些代码,这些代码可以导致JobCancellationException引发崩溃。嗨,类似的事情也发生在我身上。我将job=viewModelScope.launch(Dispatchers.IO){}包装在try-catch中。仍然异常未进入catch块。您是如何解决此问题的?您不应该在try-catch中包装launch
,您需要在launch
@Shrikant中尝试捕获代码。您需要找到导致异常的代码并使用try-catch包装它。查看此链接:是的,谢谢。试抓不是最好的方法,这个更好。这是最有意义的。如果工作不再活跃,就不要打电话通知对方。