Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are reasons to pass getActivity as the LifecycleOwner to the LiveData's observe method in a fragment?

This Google sample calls observe on LiveData in a fragment and passes getActivity() as the LifecycleOwner.

mSeekBarViewModel.seekbarValue.observe(getActivity(), new Observer<Integer>() {
        @Override
        public void onChanged(@Nullable Integer value) {
            if (value != null) {
                mSeekBar.setProgress(value);
            }
        }
    });

https://github.com/googlecodelabs/android-lifecycles/blob/master/app/src/main/java/com/example/android/lifecycles/step5_solution/Fragment_step5.java

I can't wrap my head around any reasons to do that. I only want updates as long as the fragment is active, so why not scope it to the fragment? Are there any reasons to ever NOT scope it to the fragment?

like image 274
Florian Walther Avatar asked Nov 02 '18 22:11

Florian Walther


People also ask

How do I get LifecycleOwner from fragment?

In fragments you can use getViewLifecycleOwner() method to get the lifeCycleOwner.

Why LiveData Observer is being triggered twice for a newly attached observer?

The observers method void onChanged(@Nullable T t) is called twice. That's fine. The first time it is called upon startup. The second time it is called as soon as Room has loaded the data.

In which method should you observe a LiveData object?

Attach the Observer object to the LiveData object using the observe() method. The observe() method takes a LifecycleOwner object. This subscribes the Observer object to the LiveData object so that it is notified of changes. You usually attach the Observer object in a UI controller, such as an activity or fragment.

What is LifecycleOwner?

ProcessLifecycleOwner. Class that provides lifecycle for the whole application process. A class that has an Android lifecycle. These events can be used by custom components to handle lifecycle changes without implementing any code inside the Activity or the Fragment.


1 Answers

In this case, the Fragment is inflated from a <fragment> tag in the Activity's layout, so the lifecycle of the Fragment and the Activity is always the same so it doesn't make any difference.

However, there are two cases where this fails badly:

  • If you remove() or replace() the Fragment, using getActivity() for your LifecycleOwner will result in leaking the Fragment since the LiveData holds a strong reference to the Observer (and hence, the Fragment since it is a non-static inner class) until the Activity is destroyed
  • If you detach() and then attach() the Fragment (such as with a FragmentPagerAdapter), then using the Fragment's lifecycle in onCreateView() will result in multiple Observers since onCreateView() is called each time the Fragment's view is recreated upon attach and previous Observers are not destroyed since the Fragment's lifecycle has not been destroyed.

The correct LifecycleOwner to use in onCreateView() is always getViewLifecycleOwner() since this lifecycle is destroyed when the Fragment's View is destroyed:

mSeekBarViewModel.seekbarValue.observe(getViewLifecycleOwner(), new Observer<Integer>() {
    @Override
    public void onChanged(@Nullable Integer value) {
        if (value != null) {
            mSeekBar.setProgress(value);
        }
    }
});

This prevents leaking the Fragment by using a potentially longer lifespan LifecycleOwner (like the Activity) and prevents multiple Observers being registered when using patterns like those employed by FragmentPagerAdapter.

like image 183
ianhanniballake Avatar answered Oct 26 '22 20:10

ianhanniballake