我遇到了这个有趣的问题。我需要在插入后立即做一些工作,但是随机地查看ModelScope,或者至少看起来是随机的,跳过了除第一个函数之外的功能。
例:
fun insertItem(item: SingleItem) = viewModelScope.launch {
itemsRepository.insertItem(item)
increaseAmount(item.catId)
}
因此,在此示例中,只有在全新应用程序安装后,一切才能正常运行,但是在下一个应用程序启动时,第二个功能"increaseAmount"将被随机跳过,我不知道为什么。 第一个功能之后会发生什么并不重要。我尝试了简单的"日志",它也被跳过了。视图模型范围正常吗?
编辑已检查异常。第二个函数引发作业已取消的异常:
kotlinx.coroutines.JobCancellationException: Job was cancelled; job=SupervisorJobImpl{Cancelling}@2d87ff
另外,在我的片段中,它是这样称呼的:
viewModel.insertItem(newItem)
root.findNavController().popBackStack()
因此,在调用此函数后,我返回到以前的片段。视图模型是否有可能在完成执行所有工作之前被销毁?
viewModelScope正常吗?
不,不是。在协程中,函数调用必须是顺序的。函数itemsRepository.insertItem(item)
和increaseAmount(item.catId)
必须一个接一个地调用。我看到为什么不调用第二个函数有几个原因:
- 函数
itemsRepository.insertItem(item)
引发一些异常。 - 在第二次函数调用之前取消当前协程作用域。
编辑:
ViewModel
对象的作用域为获取ViewModel
时传递给ViewModelProvider
Lifecycle
。ViewModel
将保留在内存中,直到它的作用域Lifecycle
永久消失:对于活动,当它完成时,而在片段的情况下,当它被分离时。
调用root.findNavController().popBackStack()
片段后,将分离片段,清除ViewModel
并取消协程作业。 您可以通过以下方式初始化片段中的ViewModel
:
private val viewModel: YourViewModel by activityViewModels()
以这种方式初始化viewModel
,它将作用域限定为Activity
的Lifecycle
。
要使用activityViewModels()
将下一行添加到应用程序的build.gradle文件的依赖项中,请执行以下操作:
implementation "androidx.fragment:fragment-ktx:1.2.5"