I am having this interesting problem. I need to do some work immediately after insertion, but viewModelScope randomly, or at least it looks like randomly, skips functions except for the first one.
Example:
fun insertItem(item: SingleItem) = viewModelScope.launch {
itemsRepository.insertItem(item)
increaseAmount(item.catId)
}
So in this example everything runs ok only after fresh app install, but then on the next app launches second function "increaseAmount" will be randomly skipped and i don`t know why. And it doesn't matter what goes after first function. I tried simple "Log" and it gets skipped as well. Is it normal for viewModelScope?
EDIT Checked for exceptions. Second function throws an exception that the job was cancelled:
kotlinx.coroutines.JobCancellationException: Job was cancelled; job=SupervisorJobImpl{Cancelling}@2d87ff
Also, in my Fragment it is called like this:
viewModel.insertItem(newItem)
root.findNavController().popBackStack()
So after calling this function i go back to previous Fragment. Is it possible that viewModel gets destroyed before it finishes executing all work?
Is it normal for viewModelScope?
No, it is not. In coroutines functions call must be sequential. Functions itemsRepository.insertItem(item)
and increaseAmount(item.catId)
must be called one after another. I see a couple of reasons why second function is not called:
itemsRepository.insertItem(item)
throws some exception. Edit :
ViewModel
objects are scoped to the Lifecycle
passed to the ViewModelProvider
when getting the ViewModel
. The ViewModel
remains in memory until the Lifecycle
it's scoped to goes away permanently: in the case of an activity, when it finishes, while in the case of a fragment, when it's detached.
After you call root.findNavController().popBackStack()
your fragment will be detached, the ViewModel
cleared and coroutine job cancelled. You can initialize the ViewModel
in the fragment in the following way:
private val viewModel: YourViewModel by activityViewModels()
Initializing viewModel
in this way it will be scoped to the Lifecycle
of an Activity
.
To use activityViewModels()
add next line to the dependencies of app's build.gradle file:
implementation "androidx.fragment:fragment-ktx:1.2.5"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.