onActivityCreated 已弃用:如何使用导航组件将片段添加为 MainActivity 的观察者
onActivityCreated deprecation : how to add fragments as observers of MainActivity using NavigationComponent
我刚刚看到 onActivityCreated() 将来会被弃用。我尝试实现 LifecycleOwner 和 LifecycleObserver 模式,但我不太确定我在这里做什么。
我正在使用 NavigationComponent,这意味着:
- 我有一个 MainActivity
- 我有一个 MainFragment,实例化为主片段
- 我有多个可以从此主页片段访问的片段
出于某些原因,我需要知道何时从所有这些片段(MainFragment 和子片段)创建 activity
根据我到目前为止所见,我需要:
- 在 MainActivity 中,
getLifecycle().addObserver(new MainFragment())
。并对所有子片段执行此操作(冗长无用)
- 在片段中,实现 LifecycleObserver 和
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void onCreateEvent() {
Timber.i("%s MainActivity created", TAG);
}
这似乎工作得很好,但我有一些问题:
- 语法
addObserver(new MainFragment()
打扰了我。看起来我们正在创建一个新的片段实例,而片段通常是使用 navGraph 中定义的导航实例化的。
- 正如我之前所说,如果我的 MainFragment 有 10 个子片段,我将不得不声明 11 个观察者?奇怪
- 我是否必须在 activity 生命周期的某个时刻清除这些观察者?
实施它的正确方法是什么?
编辑 1:
要回答为什么我需要知道何时创建 activity 的问题:
我需要这个,因为我需要访问我的 MainActivity 视图模型(new ViewModelProvider(requireActivity()).get(ViewModel.class)
。要调用 requireActivity()
或 getActivity()
,我需要知道何时创建 activity(使用 onActivityCreated( 很容易) )).
数据绑定是用我的 MainActivity 和这个视图模型实现的。此 activity 的布局托管加载程序以显示何时执行网络请求。
我可以执行来自 MainFragment 和子片段的请求。当我从这些片段之一执行请求时,我需要启用此加载器视图,而当我取回数据时,我需要隐藏此加载器。
是的,所有这些片段都在图中
您永远不需要等待 onActivityCreated()
调用 requireActivity()
或 getActivity()
- 只要 Fragment 附加到 FragmentManager 就可以使用它们,因此可以使用在 onAttach()
、onCreate()
、onCreateView()
、onViewCreated()
中都在调用 onActivityCreated()
之前。
这是 onActivityCreated()
被弃用的原因之一 - 它实际上与 activity 变得对 Fragment 可用无关,也与 activity 完成它的 onCreate()
(事实上,它可以被调用多次 - 每次创建 Fragment 的视图时,而不是在第一次 Activity 完成 onCreate()
之后调用一次) .
use onViewCreated(View, Bundle)
for code touching the Fragment's view and onCreate(Bundle)
for other initialization.
这些是推荐的替换,具体取决于您在 onActivityCreated()
中的代码是否正在访问 Fragment 的视图。
一旦你意识到 requireActivity()
可以在 onAttach()
等中被调用,剩下的 deprecation notice 就更有意义了:
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);
}
但是,如上所述,如果您尝试访问 activity 级别的 ViewModel,这不是您应该做的。
我刚刚看到 onActivityCreated() 将来会被弃用。我尝试实现 LifecycleOwner 和 LifecycleObserver 模式,但我不太确定我在这里做什么。
我正在使用 NavigationComponent,这意味着:
- 我有一个 MainActivity
- 我有一个 MainFragment,实例化为主片段
- 我有多个可以从此主页片段访问的片段
出于某些原因,我需要知道何时从所有这些片段(MainFragment 和子片段)创建 activity
根据我到目前为止所见,我需要:
- 在 MainActivity 中,
getLifecycle().addObserver(new MainFragment())
。并对所有子片段执行此操作(冗长无用) - 在片段中,实现 LifecycleObserver 和
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void onCreateEvent() {
Timber.i("%s MainActivity created", TAG);
}
这似乎工作得很好,但我有一些问题:
- 语法
addObserver(new MainFragment()
打扰了我。看起来我们正在创建一个新的片段实例,而片段通常是使用 navGraph 中定义的导航实例化的。 - 正如我之前所说,如果我的 MainFragment 有 10 个子片段,我将不得不声明 11 个观察者?奇怪
- 我是否必须在 activity 生命周期的某个时刻清除这些观察者?
实施它的正确方法是什么?
编辑 1:
要回答为什么我需要知道何时创建 activity 的问题:
我需要这个,因为我需要访问我的 MainActivity 视图模型(new ViewModelProvider(requireActivity()).get(ViewModel.class)
。要调用 requireActivity()
或 getActivity()
,我需要知道何时创建 activity(使用 onActivityCreated( 很容易) )).
数据绑定是用我的 MainActivity 和这个视图模型实现的。此 activity 的布局托管加载程序以显示何时执行网络请求。
我可以执行来自 MainFragment 和子片段的请求。当我从这些片段之一执行请求时,我需要启用此加载器视图,而当我取回数据时,我需要隐藏此加载器。
是的,所有这些片段都在图中
您永远不需要等待 onActivityCreated()
调用 requireActivity()
或 getActivity()
- 只要 Fragment 附加到 FragmentManager 就可以使用它们,因此可以使用在 onAttach()
、onCreate()
、onCreateView()
、onViewCreated()
中都在调用 onActivityCreated()
之前。
这是 onActivityCreated()
被弃用的原因之一 - 它实际上与 activity 变得对 Fragment 可用无关,也与 activity 完成它的 onCreate()
(事实上,它可以被调用多次 - 每次创建 Fragment 的视图时,而不是在第一次 Activity 完成 onCreate()
之后调用一次) .
use
onViewCreated(View, Bundle)
for code touching the Fragment's view andonCreate(Bundle)
for other initialization.
这些是推荐的替换,具体取决于您在 onActivityCreated()
中的代码是否正在访问 Fragment 的视图。
一旦你意识到 requireActivity()
可以在 onAttach()
等中被调用,剩下的 deprecation notice 就更有意义了:
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);
}
但是,如上所述,如果您尝试访问 activity 级别的 ViewModel,这不是您应该做的。