【问题标题】:onActivityCreated deprecation : how to add fragments as observers of MainActivity using NavigationComponentonActivityCreated 已弃用:如何使用导航组件添加片段作为 MainActivity 的观察者
【发布时间】:2020-10-02 16:09:54
【问题描述】:

我刚刚看到 onActivityCreated() 将来会被弃用。我尝试实现 LifecycleOwner 和 LifecycleObserver 模式,但我不太确定我在这里做什么。

我正在使用 NavigationComponent,这意味着:

  • 我有一个 MainActivity
  • 我有一个 MainFragment,实例化为 home 片段
  • 我有多个可以从此主片段访问的片段

出于某些原因,我需要知道何时从所有这些片段(MainFragment 和子片段)创建活动

从我目前所见,我需要:

  • 在 MainActivity 中,getLifecycle().addObserver(new MainFragment())。并为所有子片段执行此操作(这很冗长)
  • 在片段中,实现 LifecycleObserver 和
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void onCreateEvent() {
    Timber.i("%s MainActivity created", TAG);
}

这似乎运作良好,但我有一些问题:

  1. addObserver(new MainFragment() 语法让我感到不安。看起来我们正在创建一个新的片段实例,而片段通常使用 navGraph 中定义的导航进行实例化。
  2. 正如我之前所说,如果我的 MainFragment 有 10 个子片段,我将不得不声明 11 个观察者?奇怪
  3. 我是否必须在活动生命周期的某个时刻清除这些观察者?

实现它的正确方法是什么?

编辑 1: 要回答为什么我需要知道活动何时创建的问题: 我需要这个,因为我需要访问我的 MainActivity 视图模型(new ViewModelProvider(requireActivity()).get(ViewModel.class)。要调用 requireActivity()getActivity(),我需要知道活动何时创建(使用 onActivityCreated() 很容易)。 数据绑定是用我的 MainActivity 和这个 viewmodel 实现的。此活动的布局是托管一个加载程序,以显示何时执行网络请求。 我可以执行来自 MainFragment 和来自子片段的请求。当我从这些片段之一执行请求时,我需要启用这个加载器视图,当我取回数据时,我需要隐藏这个加载器。 是的,所有这些片段都在图中

【问题讨论】:

  • “出于某些原因,我需要知道何时创建活动” - 您能否准确解释这些原因是什么?您能否在onActivityCreated() 中包含您当前拥有的代码?此外,您的MainFragment 和“子”片段与您对导航组件的使用有何关联?它们都在图表中还是其他?
  • 我编辑了帖子来回答你的问题

标签: android android-lifecycle android-jetpack


【解决方案1】:

您无需等待onActivityCreated() 调用requireActivity()getActivity() - 只要将 Fragment 附加到 FragmentManager,它们都可用,因此可以在 onAttach()onCreate() 中使用, onCreateView(), onViewCreated() 都在调用 onActivityCreated() 之前。

这是 onActivityCreated() 被弃用的原因之一 - 它实际上与 Fragment 可用的活动无关,也与完成其 onCreate() 的活动无关(它,在事实上,可以多次调用——每次创建 Fragment 的视图时,而不仅仅是在 Activity 第一次完成后调用一次onCreate())。

根据deprecation notice

使用onViewCreated(View, Bundle) 用于接触片段视图的代码,onCreate(Bundle) 用于其他初始化。

这些是推荐的替换,具体取决于您在 onActivityCreated() 中的代码是否正在访问 Fragment 的视图。

一旦你意识到requireActivity() 可以在onAttach() 等中调用,deprecation notice 的其余部分就更有意义了:

要在 Fragment Activity 的 Activity.onCreate(Bundle) 被调用时获得回调,请在 onAttach(Context) 中的 Activity 生命周期中注册 LifecycleObserver,并在收到 Lifecycle.State.CREATED 回调时将其删除。

@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);
}

但是,如上所述,如果您尝试在活动级别访问 ViewModel,这不是应该做的。

【讨论】:

  • 我记得有一个 NPE 使用 getActivity() 或 requireActivity()(或者可能是 getContext() 或 requireContext(),我不记得了?),这就是为什么我认为我应该调用这些方法onActivityCreated()。现在一切都说得通了,因为正如你所说的 onActivityCreated() 的命名对于它的目的是什么具有误导性。感谢您的清晰解释,非常有帮助。
猜你喜欢
  • 1970-01-01
  • 2021-09-16
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
相关资源
最近更新 更多