'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 |