何时片段不附加到活动而仅附加到上下文?
Posted
技术标签:
【中文标题】何时片段不附加到活动而仅附加到上下文?【英文标题】:When is a fragment not attatched to an activity but only a context? 【发布时间】:2021-09-16 10:48:52 【问题描述】:the docs for Fragment.getActivity() 上面写着:Return the FragmentActivity this fragment is currently associated with. May return null if the fragment is associated with a Context instead.
但是片段怎么能不与活动关联呢?我的意思是,我不是总是需要一个 Activity 来在 android 中显示任何内容吗?
【问题讨论】:
【参考方案1】:片段不是必需与FragmentActivity
关联的。相反,它们实际上与 FragmentController
相关联,FragmentActivity
恰好代表您创建和管理,在创建、启动托管活动等时调用适当的调度方法。
这种间接级别是 Facebook 的聊天头(显示由 Service
管理的 Window
)如何能够重用 FragmentActivity
使用的相同 Fragment
实例以及 building Navigation apps for Android Automotive(使用CarAppService
显示汽车应用程序)允许您还重复使用片段。
当然,如果您的片段总是从您的一个活动中创建,那么,是的,您绝对可以假设requireActivity()
将在任何时候返回FragmentActivity
isAdded()
返回@ 987654334@ - 即在onAttach()
和onDetach()
之间。这确实包括在生命周期方法中,例如 onViewCreated()
或与您的 Fragment 视图相关的任何内容(例如 OnClickListener
)。
【讨论】:
这正是我想要的。因此,在预期的生命周期阶段之间是安全的如果您仅从活动中使用它。除非您明确这样做,否则框架不会将其附加到无 Activity 上下文。【参考方案2】:1- "... 调用 requireActivity() ... 真的安全吗?" 不,从方法的实现可以看出:
/**
* Return the @link FragmentActivity this fragment is currently associated with.
*
* @throws IllegalStateException if not currently associated with an activity or if associated
* only with a context.
* @see #getActivity()
*/
@NonNull
public final FragmentActivity requireActivity()
FragmentActivity activity = getActivity();
if (activity == null)
throw new IllegalStateException("Fragment " + this + " not attached to an activity.");
return activity;
如果活动为空,此方法将引发异常,如果您没有处理此异常,因为您可能没有处理 getActivity() 的空值,应用程序将崩溃。编译器不会仅仅因为此方法中有一个空检查而显示警告。
2- “但是片段怎么能不与活动相关联?我的意思是,我不是总是需要一个活动来在Android中显示任何东西吗?” 真的。一个附加的片段需要一个活动,但是,仅仅因为调用了 getActivity() 方法并不意味着它的片段处于附加状态。因此,它可能发生在侦听器或某些回调中,可能会在活动被销毁时调用 getActivity(),例如。由于旋转。由于这种情况,您应该通过 getActivity() 检查返回值的无效性。当活动被销毁时,关联上下文不是活动的上下文。关于这个问题有几个有趣的见解和很好的建议,你可以在这里阅读:getActivity() returns null in Fragment。
【讨论】:
我知道requireActivity()
可以抛出异常。问题是,在生命周期的哪些阶段,我们可以保证它不会抛出异常?如果没有,则该方法将不存在。有时您想使用附加活动中父布局中的值来调整视图填充。您不想多次修改填充,但也不想在 if 语句中调用代码,因为那样可能会丢失。
在 onAttach 和 onDetach 之间是安全的。在其他生命周期方法中,您可以根据需要编写代码,只需在获取活动时检查 null。
请阅读链接以获得更简洁和详细的解决方案。
“你在 onAttach 和 onDetach 之间是安全的” - 但是为什么 Google 最近弃用了onAttach(Activity)
,告诉我们使用onAttach(Context)
?对我来说,这听起来像 onAttach(Context)
可以被调用,即使没有活动,只是一个上下文。但为什么?我错过了什么?
在 onAttach(Context) 中,如果该上下文属于活动,则附加片段,并且您可以期望调用其他生命周期方法。但是,如果不是,onDetach 将立即被调用。尽管如此,您仍应检查是否为 null,因为如果在 onDetach 之后侦听器或回调调用 getActivity 它会为 null。但是如果 onAttach 被调用而 onDetach 没有被调用,getActivity 将不会返回 null。【参考方案3】:
“但是片段怎么能不与活动关联呢?” - 您始终可以创建片段的实例,而无需将其附加到任何活动。但是,如果您不将其附加到活动,它就不会显示在屏幕上(即生命周期方法不会启动)。这是一个interesting thread 来阅读。
“我的意思是,我不是总是需要 一个 Activity 来显示 Android 中的任何内容吗?” - 是的。
我发现这个google developer training 链接对于理解活动和片段之间的生命周期回调非常有用。在此处引用该链接。
Activity 的每个生命周期回调都会产生一个类似的回调 对于每个 Fragment,如下表所示。例如,当 Activity 接收到 onPause(),它会触发一个 Fragment onPause() Activity 中的每个 Fragment。
此外,@Sina 在他的回答中发布的 SO 链接对您可能期望 getActivity
何时返回 null
有一些见解。
【讨论】:
以上是关于何时片段不附加到活动而仅附加到上下文?的主要内容,如果未能解决你的问题,请参考以下文章
java.lang.IllegalStateException:未附加到上下文的片段