从`onCreateView`调用`getActivity()`是不是安全?

Posted

技术标签:

【中文标题】从`onCreateView`调用`getActivity()`是不是安全?【英文标题】:Is it safe to call `getActivity()` from `onCreateView`?从`onCreateView`调用`getActivity()`是否安全? 【发布时间】:2021-04-27 23:44:30 【问题描述】:

查看 Fragment 生命周期(例如 here),Activity 似乎在发出任何其他回调之前已附加到 Fragment(这是由 onAttach() 方法通知的)。

在我的应用程序中,它由单个 Activity 组成,第一个 Fragment 是从 Activity 的 onCreate() 方法打开的(实际上它是在 onCreate() 中完成的最后一件事)。

目前,我正在 onCreateView() 回调中初始化我的所有图形元素,包括需要构造 Activity 的某些对象(如 ArrayAdapter)的实例化,这是通过调用 getActivity() 获得的。我假设此时 Activity 保证存在,因为 onAttach() 方法已被调用。 我注意到IntelliJ警告我getActivity()返回null的可能性,可能只是因为方法被注释为@Nullable,所以我开始在网上搜索如果我的假设是真的,现在我困惑:在onCreateView() 中调用getActivity() 真的安全吗?为什么会有一个名为onActivityCreated() 的方法(我知道它现在已被弃用,但它确实有用,但它不是)?

不幸的是,文档无助于理解这一点。

【问题讨论】:

你可以在 onCreateView() 中调用它,但是为了最佳实践,它需要检查 getActivity() 是否为空,因为 android 不知道你什么时候会分离片段,所以它会显示警告以防止它崩溃。 是的.. 但最好使用requireActivity() 来保证空值安全 @NehaK 实际上可以在调用 onCreateView 之前分离 Fragment 吗? 【参考方案1】:

根据official Fragment lifecycle documentation:

FragmentManager 还负责将 Fragment 附加到其宿主 Activity 并在 Fragment 不再使用时将其分离。 Fragment 类有两个回调方法,onAttach()onDetach(),您可以在其中任何一个事件发生时重写它们以执行工作。

所以在onAttach()onDetach() 之间,getActivity() 将始终返回非空Activity,并且该页面继续说:

onAttach() 总是在任何 Lifecycle state changes 之前调用。

onDetach() 总是在任何Lifecycle state changes 之后调用。

所以,是的,onCreateView(),作为生命周期状态更改,将意味着getActivity() 返回一个非空值。

这正是requireActivity() 的用例——它允许你告诉片段系统你知道在那个时间点getActivity() 将返回一个非空值并且你'想要一个编译时保证,在您的 requireActivity() 调用之后的任何代码都可以访问非空 Activity。

至于onActivityCreated(),根据this answer,这是一个非常糟糕的命名方法:

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

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

当然,请注意像 ArrayAdapter 这样的 API需要 Activity - 它们需要 ContextgetContext()requireContext() 中有类似的方法,如果您专门寻找 Context,则首选这些方法。

【讨论】:

以上是关于从`onCreateView`调用`getActivity()`是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

OnCreateView 多次调用/使用 ActionBar 和 Fragments

多次调用片段 onCreateView

再次调用“onCreateView” - Android

为啥popbackstack会调用fragment的onCreateView?

ViewPager Fragment OncreateView根据切换的标签数多次调用

是否可以在片段中手动调用 onCreateView?