In certain case like Home Widget (AppWidgetProvider
), I don't have access to Activity
or Fragment
.
Usually, I use ProcessLifecycleOwner.get()
, or the following LifeCycleOwner
to observe LiveData
.
public enum ForeverStartLifecycleOwner implements LifecycleOwner {
INSTANCE;
private final LifecycleRegistry mLifecycleRegistry;
ForeverStartLifecycleOwner() {
mLifecycleRegistry = new LifecycleRegistry(this);
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
In most situation, in the callback of LiveData
, I will try to remove LifeCycleOwner
from further observing LiveData
, by using liveData.removeObserver
.
However, there are situation where
In such situation, will it cause resource leakage? For instance, GC notice a long life LifeCycleOwner
is observing LiveData A
. Although LiveData
A is already out of scope, GC will not free-up LiveData A
, because a long living LifeCycleObserver
still observing it?
If so, how can I resolve this kind of leakage?
Yes, that's the whole point of the new lifecycle-aware components, no need to unsubscribe/remove observers. Show activity on this post. TL;DR: You're better off explicitly removing the observer when you are done with it, or use something that handles this automatically, such as LiveData .
LiveData is lifecycle-aware, following the lifecycle of entities such as activities and fragments. Use LiveData to communicate between these lifecycle owners and other objects with a different lifespan, such as ViewModel objects.
Else, we can use callback or RxJava in ViewModel. Another compromise is implement MediatorLiveData (or Transformations) and observe (put your logic here) in ViewModel. Notice MediatorLiveData observer won't trigger (same as Transformations) unless it's observed in Activity/Fragment.
Lifecycle Awareness: ViewModel objects are also lifecycle-aware. They are automatically cleared when the Lifecycle they are observing gets permanently destroyed. Data Sharing: Data can be easily shared between fragments in an activity using ViewModels .
will it cause resource leakage?
Answer : I don't think so that this kind of scenario will make memory leak.
Why?
Because, as we can see that once LiveData
is out of scope for any LifecyclerOwner
, it removes reference if you set your LifecycleOwner
at DESTROYED state.
see observe()
method documentation;
obesrve() :
Adds the given observer to the observers list within the lifespan of the given owner. The events are dispatched on the main thread. If
LiveData
already has data set, it will be delivered to the observer.The observer will only receive events if the owner is in STARTED or RESUMED state (active).
If the owner moves to the DESTROYED state, the observer will automatically be removed.
When data changes while the owner is not active, it will not receive any updates. If it becomes active again, it will receive the last available data automatically.
LiveData
keeps a strong reference to the observer and the owner as long as the givenLifecycleOwner
is not destroyed. When it is destroyed,LiveData
removes references to the observer & the owner.If the given owner is already in DESTROYED state,
LiveData
ignores the call.If the given owner, observer tuple is already in the list, the call is ignored. If the observer is already in the list with another owner,
LiveData
throws anIllegalArgumentException
.
So, according to above documentation, from line :
If the owner moves to the DESTROYED state, the observer will automatically be removed.
If the given owner is already in DESTROYED state, LiveData ignores the call.
it's clear that if your LifecycleOwner
has no scope (already in DESTROYED state), then LiveData
removes it's strong reference thus there's no chance of memory leak.
how can I resolve this kind of leakage? & get callback all the time:
Answer : You've already created your own LifecycleOwner
, so I'll suggest you to handle it yourself. make your LiveData
to observeForever()
& handle removal (removeObserver()
) yourself once your LifecycleOwner
reaches to DESTROYED state.
this will not cause memory leak. because it's stated in document: (This means that the given observer will receive all events and will never be automatically removed)
observeForever() :
Adds the given observer to the observers list. This call is similar to
observe(LifecycleOwner, Observer)
with a LifecycleOwner, which is always active. This means that the given observer will receive all events and will never be automatically removed. You should manually callremoveObserver(Observer)
to stop observing thisLiveData
. WhileLiveData
has one of such observers, it will be considered as active.If the observer was already added with an owner to this
LiveData
,LiveData
throws anIllegalArgumentException
.
This will help you receive callback all the time, you just need to handle how you can remove callback once done.
Hope it helps !
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With