【问题标题】:Android kotlin coroutines, viewModelScope behaviorAndroid kotlin 协程,viewModelScope 行为
【发布时间】:2020-10-07 14:52:27
【问题描述】:

我遇到了这个有趣的问题。我需要在插入后立即做一些工作,但是 viewModelScope 随机地,或者至少看起来像随机地,跳过除了第一个之外的函数。

例子:

fun insertItem(item: SingleItem) = viewModelScope.launch {
        itemsRepository.insertItem(item)
        increaseAmount(item.catId)
    }

所以在这个例子中,只有在新的应用程序安装后一切运行正常,但是在下一个应用程序启动时,第二个函数“increaseAmount”将被随机跳过,我不知道为什么。 第一个函数之后的内容并不重要。我尝试了简单的“日志”,它也被跳过了。 viewModelScope 正常吗?

编辑 检查异常。第二个函数抛出作业被取消的异常:

kotlinx.coroutines.JobCancellationException: Job was cancelled; job=SupervisorJobImpl{Cancelling}@2d87ff

另外,在我的 Fragment 中它是这样调用的:

viewModel.insertItem(newItem)
root.findNavController().popBackStack()

所以在调用这个函数之后,我会回到之前的 Fragment。 viewModel 是否有可能在完成所有工作之前被销毁?

【问题讨论】:

  • itemRepository.insertItem 可能会抛出异常。你检查了吗?

标签: android kotlin viewmodel kotlin-coroutines coroutinescope


【解决方案1】:

viewModelScope 正常吗?

不,不是。在协程中,函数调用必须是顺序的。函数itemsRepository.insertItem(item)increaseAmount(item.catId) 必须一个接一个地调用。我看到了不调用第二个函数的几个原因:

  1. 函数itemsRepository.insertItem(item) 引发一些异常。
  2. 当前协程作用域在第二次函数调用之前被取消。

编辑

ViewModel 对象的范围为Lifecycle,在获取ViewModel 时传递给ViewModelProviderViewModel 一直保留在内存中,直到 Lifecycle 永久消失:在活动的情况下,当它完成时,而在片段的情况下,当它分离时。

在您调用root.findNavController().popBackStack() 后,您的片段将被分离,ViewModel 被清除并取消协程作业。 您可以通过以下方式初始化片段中的ViewModel

private val viewModel: YourViewModel by activityViewModels()

以这种方式初始化viewModel,它将被限定为ActivityLifecycle

要使用activityViewModels(),在应用的build.gradle文件的依赖项中添加下一行:

implementation "androidx.fragment:fragment-ktx:1.2.5"

【讨论】:

  • 好的,所以我检查了异常。第一个函数不会抛出任何东西,但第二个函数会抛出一个工作确实被取消了。如何查看取消的原因?
  • 在 Android Studio 中你可以在 logcat 中检查异常
  • 我能看到的唯一例外是我上面提到的那个,只有在我用 try/catch 显示它之后
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
相关资源
最近更新 更多