I have a use case which I want to use coroutine but a little confused how to implement it.
A ViewModel which has a scope and bind to the UI lifecycle and call an API from the repository:
class UserViewModel(): CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
fun showUser() {
launch {
val user = repo.getUser()
livedata = user
}
}
fun onClean() {
job.cancel()
}
}
The repository use coroutine to build the network call like this:
suspend fun getUser() = GlobalScope { ... }
The use case is the repository function need to be always fully executed once the API is called from ViewModel since we need to capture all the network response from the server.
How I can make sure the coroutine in the repository is always executed but the ViewModel coroutines will be canceled to avoid memory leak once view model is cleared?
According to the documentation of the
GlobalScope
I think we can rely that coroutine, launched using the global CoroutineScope, is always executed. The documentation says:I've implemented some test code, and when the
job
was canceled inside theUserViewModel
the coroutine in repository continued executing. Here is the code with my comments:Additionally we can reduce
showUser()
function:using extension function
then
:If you develop for Android and want to be sure your IO operation is executed completely even after cleaning up the ViewModel, use WorkManager. It is intended for asynchronous and deferrable tasks that require a guarantee that the system will run them even if the app exits.