Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will it cause resource leakage if I have a long life LifeCycleOwner keep observing LiveData?

Tags:

android

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

  1. LiveData fails to trigger callback.
  2. Hence, I didn't remove LifeCycleOwner from LiveData in LiveData's callback.

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?

like image 240
Cheok Yan Cheng Avatar asked Oct 03 '18 06:10

Cheok Yan Cheng


People also ask

Should I remove lifecycle observer?

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 .

Is LiveData lifecycle-aware?

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.

In which method should you observe a LiveData object?

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.

How Mvvm is lifecycle-aware?

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 .


1 Answers

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 given LifecycleOwner 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 an IllegalArgumentException.


TL;DR

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 call removeObserver(Observer) to stop observing this LiveData. While LiveData 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 an IllegalArgumentException.

This will help you receive callback all the time, you just need to handle how you can remove callback once done.

Hope it helps !

like image 81
Jeel Vankhede Avatar answered Sep 30 '22 17:09

Jeel Vankhede