'Cancel viewModelScope and re-use it later on
I'm using Coroutines for dealing with async jobs:
viewModelScope.launch {
val userResponse = getUsers() //suspendable function
}
What I want to do is stop all existing/ongoing coroutine jobs. Idea is that I click on different tabs. If getUsers() takes up to 5 seconds and user clicks from User tab to Job tab, I want that existing API call is stopped and response is not observed.
I tried to do viewModelScope.cancel(), but that seems not to be working.
Question is - how to cancel existing jobs on button click?
Solution 1:[1]
Define a reusable Job like following in the ViewModel class:
private var job = Job()
get() {
if (field.isCancelled) field = Job()
return field
}
Pass it to all of launch coroutine builders as the parent Job:
viewModelScope.launch(job) {
val userResponse = getUsers()
}
viewModelScope.launch(job) {
// some other work
}
...
On button click, just cancel the parent job:
fun cancelAll() {
job.cancel()
}
Solution 2:[2]
You can get its Job through its CouroutineContext like this:
viewModelScope.coroutineContext[Job]
To stop all existing/ongoing coroutine jobs you can call its cancel method:
viewModelScope.coroutineContext[Job]?.cancel()
If you need to start other coroutines eventually then call its cancelChildren method instead:
viewModelScope.coroutineContext[Job]?.cancelChildren()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | aminography |
| Solution 2 | Glenn Sandoval |
