Issue
how do i correctly use coroutines in a Library class which has nothing to do with the activity lifecycle?
For now, i created a private property in my class:
private val coroutineScope = CoroutineScope(Dispatchers.Main)
and have a cancel method, to cancel the scope.
public fun cancel() {
coroutineScope.coroutineContext.cancelChildren()
}
Is there any cleaner way to make this work, without having to call cancel on my library class in onPause/OnStop?
EDIT:
Also, an additional question: Does it matter, if my created CoroutineContext is in a Singleton? Like this:
public object MyObject {
private val coroutineScope = CoroutineScope(Dispatchers.Main)
}
Is there any danger of memory leaks or similar?
Solution
Simply said no, you create a scope when you need it, you cancel it when you don't need it anymore. Scope takes care of the lifecycle of all the coroutines
fired from it. A coroutine is an instance of suspendable computation. Once you do not need that computation anymore you cancel it, in order to save computational power where it's really needed. To avoid tracking all the fired coroutine by their jobs, we have a scope. Imagine having 1000 independent coroutines and having to track 1000 jobs to cancel them, instead of that, we have a scope to cancel them all at once. You can simply call scope.cancel()
.
One way how you can avoid manually calling cancel()
in onPause/onStop
is to use observation pattern, make your library class implement LifecycleObserver
interface and have it observe the Lifecycle
of an Activity/Fragment
of interest.
A Singleton is just a single ever existing instance of a class, there's no reason why would there be any problems having CoroutineScope
instance inside of it.
Answered By - J.Grbo
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)