Issue
I just saw that onActivityCreated() is going to be deprecated in future. I try to implement LifecycleOwner and LifecycleObserver pattern but I'm not quite sure about what I'm doing here.
I'm using NavigationComponent, which meens :
- I have a MainActivity
- I have a MainFragment, instanciated as the home fragment
- I have multiple fragments that can be accessed from this home fragment
For some reasons I need to know when activity is created from all of these fragments (MainFragment and sub fragments)
From what I've seen until now, I need to :
- In the MainActivity,
getLifecycle().addObserver(new MainFragment())
. And do this for all sub fragments (which is verbose for nothing) - In fragments, implements LifecycleObserver and
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void onCreateEvent() {
Timber.i("%s MainActivity created", TAG);
}
This seems to work well, but I have some questions :
- The syntax
addObserver(new MainFragment()
disturbs me. It looks like we are creating a new fragment instance, while the fragment is normally instantiated with the navigation defined in the navGraph. - As I said before, if I have my MainFragment with 10 sub fragments, I'll have to declare 11 observers ? Weird
- Do I have to clear these observers at some point in the activity lifecycle ?
What is the proper way to implement it ?
EDIT 1:
To answer the question why I need to know when the activity is created :
I need this because I need to access my MainActivity viewmodel (new ViewModelProvider(requireActivity()).get(ViewModel.class)
. To call requireActivity()
or getActivity()
I need to know when the activity is created (was easy with onActivityCreated()).
Databinding is implemented with my MainActivity and this viewmodel. The layout of this activity is hosting a loader to show when network requests are performed.
I can perform requests from the MainFragment and from the sub fragments. When I perform a request from one of these fragments I need to enable this loader view, and when I got datas back I need to hide this loader.
And yes, all these fragments are in the graph
Solution
You have never needed to wait for onActivityCreated()
to call requireActivity()
or getActivity()
- those are both available as soon as the Fragment is attached to the FragmentManager and hence can be used in onAttach()
, onCreate()
, onCreateView()
, onViewCreated()
all before onActivityCreated()
is called.
This is one of the reasons why onActivityCreated()
was deprecated - it actually has nothing to do with the activity becoming available to the Fragment, nor does it have anything to do with the activity finishing its onCreate()
(it, in fact, can be called multiple times - every time the Fragment's view is created, not just once after the first time the Activity finishes onCreate()
).
As per the deprecation notice:
use
onViewCreated(View, Bundle)
for code touching the Fragment's view andonCreate(Bundle)
for other initialization.
Those are the recommended replacements, depending on whether the code you had in onActivityCreated()
was accessing the Fragment's views or not.
Once you realize that requireActivity()
can be called in onAttach()
, etc., the rest of the deprecation notice makes more sense:
To get a callback specifically when a Fragment activity's
Activity.onCreate(Bundle)
is called, register aLifecycleObserver
on the Activity's Lifecycle inonAttach(Context)
, removing it when it receives theLifecycle.State.CREATED
callback.
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
// Register a LifecycleObserver on the Activity's Lifecycle in onAttach()
requireActivity().getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void onCreateEvent() {
// Remove the LifecycleObserver once you get a callback to ON_CREATE
requireActivity().getLifecycle().removeObserver(this);
// Then do your logic that specifically needs to wait for the Activity
// to be created
Timber.i("%s MainActivity created", TAG);
}
But, as mentioned above, this is not what you should be doing if you are trying to access a ViewModel at the activity level.
Answered By - ianhanniballake
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.