从`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 - 它们需要 Context
。 getContext()
和 requireContext()
中有类似的方法,如果您专门寻找 Context
,则首选这些方法。
【讨论】:
以上是关于从`onCreateView`调用`getActivity()`是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章
OnCreateView 多次调用/使用 ActionBar 和 Fragments
为啥popbackstack会调用fragment的onCreateView?