What should be lifeCycleOwner of LiveData-Fragment or Activity? - android

Will Activity be lifeCycleowner of LiveData?
or
Will Fragment be lifeCycleowner of LiveData?

The answer is as per my understanding and I would say, it depends on where LiveData is being used or called from?
Let's go through some basics.
LifecycleOwner by definition means
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.
Lifecycle
Lifecycle-aware components perform actions in response to a change in the lifecycle status of another component, such as activities and fragments. These components help you produce better-organized, and often lighter-weight code, that is easier to maintain.
Since the Lifecycle of Activity and Fragments are different.
Activity - Activity has its own lifecycle
Fragment - Each Fragment instance has its own lifecycle. To manage the lifecycle, Fragment implements LifecycleOwner.
Fragments are basically contained inside an Activity; so if the Activity is destroyed, Fragments will also be destroyed.
But it's not necessary that if fragments are destroyed, Activity will also be destroyed.
Live Data
You can register an observer paired with an object that implements the LifecycleOwner interface. This relationship allows the observer to be removed when the state of the corresponding Lifecycle object changes to DESTROYED.
Now coming back to your question.
when LiveData is observed in Activity, the lifecycle owner is Activity itself.
when LiveData is observed in Fragment, the lifecycle owner is Fragment itself.

What should be lifeCycleOwner of LiveData-Fragment or Activity?
It really depends on where you're using liveData. LiveData is lifecycle-aware, which means they respect the lifecycle of android app components.
If you are using liveData to observe data inside activity, then you should observe using activity.
If you are using liveData to observe data inside a fragment, then there is no point in using activity as lifecycleOwner. Using activity would lead to a memory leak, if fragment is replaced or removed, as liveData would still hold a strong reference to the fragment, which will be kept until activity is destroyed.
We should use viewLifecycleOwner inside fragments, as they are bind to the lifecycle of fragments.

As stated in the Google documentation
Each Fragment instance has its own lifecycle. When a user navigates and interacts with your app, your fragments transition through various states in their lifecycle as they are added, removed, and enter or exit the screen.
So each fragment and activity have their own lifecycle.
When you observer LiveData in the fragment or activity you pass the lifecycleowner associated with that fragment or activity.

Related

Communicating between Activities and Fragments when using Navigation Architecture Component

I want to let the host Activity know when something happens in a Fragment. Traditionally, I would have an interface with a callback that the Fragment can call, but now we are ofc using the navigation architecture component.
Is there a way to pass a reference to the host activity down to the fragments or how would I otherwise solve the "Communication between activities and fragments" situation?
Thanks!
You can use the LiveData data holder class for such purposes.
Here is an article explaining both Fragment <--> Fragment communication and Activity <--> Fragment communication.
you can have a shared ViewModel between your activity and all of your fragments. and use liveData in that viewModel. so when something happens in the fragments you change the liveData and you observe the liveData in the activity
You can use a Shared ViewModel (https://developer.android.com/topic/libraries/architecture/viewmodel#sharing)
It would be alive while the activity is and all child fragments can access it.
A LiveData in a Shared ViewModel, for example, could be listened to in all the fragments. If one of those fragments change the data all others would get that change.

LiveData observing in Fragment

As of 2019, I'm trying to follow a best practice on where to start observing LiveData in Fragments and if I should pass this or viewLifecycleOwner as a parameter to the observe() method.
According to this Google official documentation, I should observe in onActivityCreated() passing this (the fragment) as parameter.
According to this Google sample, I should observe in onViewCreated() passing viewLifecycleOwner as parameter.
According to this I/O video, I shouldn't use this but instead viewLifecycleOwner, but doesn't specify where should I start observing.
According to this pitfalls post, I should observe in onActivityCreated() and use viewLifecycleOwner.
So, where should I start observing? And should I either use this or viewLifecycleOwner?
If observing from an Activity you can observe on onCreate() and use this for the LifecycleOwner as stated here:
If you have a lifecycle-aware component that is hooked up to the lifecycle of your activity it will receive the ON_CREATE event. The method annotated with #OnLifecycleEvent will be called so your lifecycle-aware component can perform any setup code it needs for the created state.
Now if you are observing within a Fragment you can observe on onViewCreated() or onActivityCreated() and you should use getViewLifecycleOwner() and here is why:
Get a LifecycleOwner that represents the Fragment's View lifecycle. In most cases, this mirrors the lifecycle of the Fragment itself, but in cases of detached Fragments, the lifecycle of the Fragment can be considerably longer than the lifecycle of the View itself.
As in the I/O talk Yigit says, the Fragment and its view has different lifecycles. You would need to identify if your LiveData is related to the fragment or its view and pass the one desired. The compiler will accept both since both are implementations of LifecycleOwner
It doesn't matter whether you do it on onViewCreated or onActivityCreated. Both are called when the fragment is inflated, onViewCreated first, onActivityCreated afterwards. It's really a matter of preference.
The LiveData object takes a LifecycleOwner, and both Fragment and Activity implement the interface, so you just need to pass this.

Creating my own ViewModelStore to control ViewModel lifecycle

It is stated in google example that to communicate from fragment to fragment, you could use the ViewModel scoped to the Activity. The problem with this approach is that, then the ViewModel will last until the Activity is destroyed.
In a Single Activity Application, this means that the activity will be littered with ViewModels which might not be needed anymore. You will also have problem with states if these ViewModels won't be cleared properly.
So I look around at how to alter the lifecycle of the ViewModel so that I doesn't have to be tied to the Activity lifecycle but be longer than the lifecycle of a Fragment. This will then be very useful for Multi-step / Transactional flow of screens where the requirements are filled-up during the screen flow process.
So basically, I would want a ViewModel to be scoped less than the activity but longer than a fragment.
To accomplish this, I created my own ViewModelStore and persist it across configuration the same way FragmentActivity persist its own ViewModelStore. Then when initializing the view model I will use,
ViewModelProvider(myCustomViewModelStore, myFactory).get(SomeViewModelClass::class.java)
Since the ViewModel is not scoped to my custom ViewModelStore, I could easily call viewModelStore.clear() to control the lifecycle of the ViewModel.
I was wondering whether this is a good idea and whether someone out there is using the same idea.
Thanks in advance!
As of Navigation Component 2.1.0-aplha02, ViewModels can now be scoped to transaction flows through the Navigation Component navigation graph.

Are there any reasons to ever scope LiveData to a fragment's lifecycle, rather than to the fragment's view's lifecycle?

If we scope LiveData to the lifecycle of a fragment by passing this to the observe method, the fragment doesn't get immediate updates if it is only detached from the activity, but not removed, because only the view is destroyed, not the fragment instance itself.
Instead, we can scope LiveData to the lifecycle of the view of the fragment, by calling observe in onActivityCreated and passing getViewLifecycleOwner() rather than this.
Is there any reason to not scope the LiveData to the fragment's view?
If your fragment does not have a UI then you will need to scope it with fragment's lifecycle.
Many people/libraries used and still use headless(UI-Less) worker fragments to have lifecycle awareness to safely pass on asynchronously retrieved data (Network Call) to the UI. (Similar to what Loaders do)

Meaning of fragment having its own lifecycle

Everywhere it is written that fragments have their own lifecycle . Also fragment life cycle depend on activity's lifecycle.What is the meaning of fragment's own lifecycle if it is dependent on activity's lifecycle?
First of all you need to understand what are lifecycle methods are and when are they called/invoked. Lifecycle methods are basically invoked at the different state of your Activty/Fragment. For example when you first launch your activity the following flow of events/methods are called depending upon the state of your activity. For example : When your activity is first launched OnCreate is called, when your activity is no longer visible then onStop is called. So basically you first need to learn at which state are these different activities called.Below is a great referential flowchart for the same.
Activity lifecycle methods :
Fragment lifecycle methods :
Now, when you create a fragment it is inflated into the activty. And it has its own set of lifecycle events/methods which are called and since the fragment is inflated into the activty when the state of your activity changes it effects the fragment and correspondingly different lifecycle methods of the fragments are called. Below is another pictorial representation of the relation between the lifecycle methods of the activity and the fragment.
Image source : Google Images
The activity lifecycle is fairly simple in comparison to the fragment lolcycle (image from Square's Advocating against Android Fragments)

Categories

Resources