Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LifecycleOwner: difference between Fragment (self) and Fragment#viewLifecycle

Using Android X and the Android Architecture Components, namely the following...

  • Navigation
  • Lifecycle
  • ViewModel

... has made Android development much easier for better and more stable apps.

When using a ViewModel exposing LiveDatas for a Fragment, there are currently two LifecycleOwners that can be used to oberve:

  1. the Fragment itself or
  2. the Fragment's property mViewLifecycleOwner.

Up until now, I have always and exclusively use the Fragment itself for any and all LiveData exposed by ViewModels.

As I like to live on the edge by frequently upgrading to the latest alphas & betas, I have recently upgraded to:

  • navigation ktx version 2.2.0-rc01 ;
  • activity ktx version 1.1.0-rc01 ;
  • fragment ktx version 1.2.0-rc01 ;
  • lifecycle ktx version 2.2.0-rc01 ;

OK luckily, at this date (1st nov 2019), there were all available as release candidates.

This had the consequence to warn me in old java code:

enter image description here

How come there is actually two LifecycleOwners ?

Should I also follow this warning when setting the lifecycle owner of the Fragment's databound layout (using the Databinding library) ?

Then what's the use for the Fragment itself as a LifecycleOwener?

like image 351
Mackovich Avatar asked Nov 01 '19 16:11

Mackovich


People also ask

How many types of LifecycleOwner available in fragment when and which LifecycleOwner should pass?

When using a ViewModel exposing LiveData s for a Fragment , there are currently two LifecycleOwners that can be used to oberve: the Fragment itself or. the Fragment 's property mViewLifecycleOwner .

What is the difference between a fragment and an activity?

Activity is an application component that gives a user interface where the user can interact. The fragment is only part of an activity, it basically contributes its UI to that activity. Fragment is dependent on activity. It can't exist independently.

Why onActivityCreated is deprecated?

Need for onActivityCreated() deprecation In such similar fashion android developers saw the tight coupling of code dependent to the Activity's life cycle. And they decided that it is not a good practice anymore to be dependent on the activity attach to do certain things inside the fragment.


1 Answers

There are two different lifecycles because the Fragment itself lives longer than the Fragment's view.

There are a number of events that can cause the Fragment's view to be destroyed, but currently keep the Fragment itself alive:

  1. Putting the Fragment on the back stack (i.e., when you navigate() to another Fragment)
  2. Calling detach() on a Fragment
  3. Calling setMaxLifecycle(Lifecycle.State.CREATED) on a Fragment

In these cases, the Fragment's view is destroyed, moving the Fragment view lifecycle to DESTROYED. However, the lifecycle of Fragment itself is not destroyed - it generally stays as CREATED. This means that the Fragment can go through multiple cycles of onCreateView() -> onViewCreated() -> onDestroyView() while only going through onCreate() once.

Where this becomes a problem is when it comes to how LiveData works. When you observe a LiveData, LiveData automatically unregisters the observer when the lifecycle reaches DESTROYED. But if you use the Fragment's lifecycle to observe in onCreateView(), etc., that registered observer will still exist after onDestroyView(), despite the view being destroyed. This means that the second time your Fragment goes through onCreateView(), you'll actually create a second active Observer, with both running simultaneously. Then three Observers the next time and on and on.

By using the view LifecycleOwner in onCreateView()/onViewCreated(), you ensure that you'll only have one active Observer running at a time and that Observers tied to previous view instances are correctly destroyed along with the view. Therefore, yes, you should always use getViewLifecycleOwner() as the LifecycleOwner when in onCreateView() or onViewCreated(), including when using Data Binding.

Of course, if you're registering an Observer in onCreate(), then the view LifecycleOwner does not exist yet (it is created right before onCreateView()) and you don't have the multiple registration problem, which is why the Lint check specifically does not apply to any registrations done at onCreate() time. In those cases, using the Fragment's lifecycle itself is absolutely correct.

As per the Fragments: Past, Present, and Future talk, one future improvements for Fragments is going to be combining the two lifecycles together, always destroying the Fragment whenever the Fragment's view is destroyed. This is not yet available in any shipped version of Fragments, alpha or otherwise.

like image 50
ianhanniballake Avatar answered Oct 18 '22 05:10

ianhanniballake