Android Kotlin协程,viewModelScope行为

Android kotlin coroutines, viewModelScope behavior

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

例:

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

因此,在此示例中,只有在全新安装应用程序后一切正常,但是在下一个应用程序启动后,第二个功能" increaseAmount"将被随机跳过,我不知道为什么。
而且,第一个功能执行完之后没有关系。 我尝试了简单的"日志",它也被跳过了。 viewModelScope是否正常?

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

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

另外,在我的片段中,它的调用方式如下:

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

因此,在调用此函数后,我将返回上一片段。 viewModel是否有可能在完成所有工作之前被销毁?


viewModelScope是否正常?

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

  • 函数itemsRepository.insertItem(item)引发一些异常。
  • 当前协程范围在第二个函数调用之前被取消。
  • 编辑:

    当获取ViewModel时,ViewModel对象的范围限定为传递给ViewModelProviderLifecycleViewModel保留在内存中,直到它的作用域永久消失:在活动的情况下,完成时,在片段的情况下,脱离时。

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

    1
    private val viewModel: YourViewModel by activityViewModels()

    以这种方式初始化ViewModel的范围将是ActivityLifecycle

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

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