gpt4 book ai didi

android - Kotlin:如何绕过 CancellationException

转载 作者:行者123 更新时间:2023-12-02 12:04:53 24 4
gpt4 key购买 nike

我正在将一些旧的 RxJava 代码移植到 Coroutines。使用 RxJava,我可以在我的 Activity 中做到这一点:

someBgOperation()
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(MyActivity.this)))
.subscribe(
MyActivity.this::onSuccess,
MyActivity.this::onError
);

如果 Activity 被关闭,autodispose 库将取消 Observable。在这种情况下,RxJava 不会调用错误处理程序,因此可以安全地在错误处理程序中执行与 UI 相关的操作,例如显示对话框。

现在在 Kotlin 中,我们可以从 lifecycleScope 启动这个等效代码。在 Activity 中,或在 viewModelScope如果使用 ViewModel:
viewModelScope.launch {
try {
someBgOperation()
} catch (e: Exception){
//show dialog
}
}

当 Activity 关闭时,这两个范围都会自动取消,这正是 Autodispose 所做的。但是 catch block 不仅会执行 someBgOperation 引发的正常错误。本身,但也与 CancellationException s 由 coroutines 库在后台用于处理取消。如果我在 Activity 关闭时尝试在那里显示一个对话框,我可能会遇到新的异常。所以我被迫做这样的事情:
viewModelScope.launch {
try {
someBgOperation()
} catch (ce: CancellationException){
//do nothing, activity is closing
} catch (e: Exception){
//show dialog
}
}

这感觉比 Rx 版本更冗长,并且它有一个空的 catch 子句,它将在 lint 输出中显示一个警告。在其他情况下,我在 try-catch 之后做更多事情,我被迫从 CancellationException 返回。 catch 以保持 UI 安全(并且这些返回是标记返回)。我发现自己一次又一次地重复这个丑陋的模板。

有没有更好的方法来忽略 CancellationException?

最佳答案

我可以提出两种解决方案。首先,额外的catch(e: CancellationException)子句看起来有点冗长。您可以将代码简化为:

viewModelScope.launch {
try {
someBgOperation()
} catch (e: Exception) {
if (e !is CancellationException) // show dialog
}
}

另一方面,您可以使用 Kotlin Flow 的 catch运算符旨在为此目的而忽略取消。由于您实际上不会通过流发送任何值,因此您应该使用 Flow<Nothing> :
flow<Nothing> {
someBgOperation()
}.catch { e ->
// show dialog
}.launchIn(viewModelScope)

关于android - Kotlin:如何绕过 CancellationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62220286/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com