onActivityCreated deprecation : how to add fragments as observers of MainActivity using NavigationComponent

风流意气都作罢 提交于 2021-01-29 12:37:47

问题


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 :

  1. 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.
  2. As I said before, if I have my MainFragment with 10 sub fragments, I'll have to declare 11 observers ? Weird
  3. 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


回答1:


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 and onCreate(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 a LifecycleObserver on the Activity's Lifecycle in onAttach(Context), removing it when it receives the Lifecycle.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.



来源:https://stackoverflow.com/questions/64174868/onactivitycreated-deprecation-how-to-add-fragments-as-observers-of-mainactivit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!