Android 片段 getActivity() = null
Posted
技术标签:
【中文标题】Android 片段 getActivity() = null【英文标题】:Android Fragment getActivity() = null 【发布时间】:2014-02-03 05:33:56 【问题描述】:我在我的应用程序中使用片段。使用它们时最常见的问题是使用 getActivity() 时的 NPE。我知道我们可以通过每次检查getActivity() != null
或检查片段isAdded()
来解决它。
在我的一门课程中,我在 60 多个地方获得了活动的上下文。检查 getActivity() 是否不为 null 或者是否仍将片段添加到所有地方的活动中,这会使代码变得丑陋、更大且不可维护。有没有其他方法来处理这个? 当它从活动中移除时,甚至有可能破坏片段(并停止它在被移除时所做的任何工作)?
Also Is this way a suggested one?
【问题讨论】:
【参考方案1】:根据我的经验,大多数 getActivity() 返回 null 的情况都是异步回调。
例如,您的 Fragment 触发了一个 AsyncTask,然后在后台作业完成之前被删除,然后当后台作业完成并在 onPostExecute() 中调用 getActivity() 时,它将获得 null,因为该 Fragment 已经脱离活动。
我的解决方案:
1.在每个异步回调开始时检查 getActivity()==null,如果是这种情况,则中止该方法。
2.在onDetach()中取消异步作业。
而且我认为这比在 onAttach() 中保存活动实例更好,因为既然您的片段已被删除,为什么还要费心去做所有留在回调中的工作(在大多数情况下是 UI 代码)?
【讨论】:
对我来说这似乎是最好的解决方案! 非常好的解决方案!而且这个解释不明显!好点子! 哇...这个答案是最好的。就我而言,getActivity() 有时会返回 null,我不知道 getActivity() 何时返回 null 以及如何处理。感谢@handhand,我意识到在我的代码中 getActivity() 在 OkHttp Callback 中,它异步工作。此外,当 getActivity() 为 null 时,我什么都不用做,因为 Activity 和相关的 Fragments 已经消失了。【参考方案2】:我的解决方案是重写 BaseActivity 中的 onSaveInstanceState 方法:
@Override
protected void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
//solution of fragment.getActivity() is null
outState.remove("android:support:fragments");
【讨论】:
【参考方案3】:getActivity 将在方法 - onActivityCreated() 中重新初始化。
所以在 onActivityCreated() 之后调用 getActivity() 更安全(根据片段的生命周期http://developer.android.com/guide/components/fragments.html) - 例如在 onStart() 中 - 在这种情况下它永远不会为空 - 不需要做无用的检查,比如isAdded 和 getActivity != null。
附:如果我们使用该解决方案:
@Override
public void onAttach(Activity activity)
super.onAttach(activity);
mActivity = activity;
mActivity 永远不会为 null - 但后来在方法 onActivityCreated() getActivity() 中变得与 mActivity 不同。 我的意见 - 确定我们可以将整个活动保存在变量中,但遵循 android 片段生命周期工作流程并在 onActivityCreated() 之后立即获取活动会更安全
【讨论】:
如果您的片段是静态的,则可能存在内存泄漏,我个人遇到过这个问题。永远不要在片段中收集活动参考。如果在 onDetach() 中强制将其标记为 null 是的,即使活动不是静态的,这也是合理的。此外,我从不使用静态片段 - 这很危险(就像你说的 - 内存泄漏),而且我从未见过它可能有用的情况。【参考方案4】:我没有找到解决方案,可能是因为如果您考虑lifecycle of a fragment,您应该能够理解何时检查空值。
【讨论】:
是的,我知道分离的片段还活着:(我希望有办法!! 我明白你的意思。基本上我倾向于做的是检查我的活动/上下文,当我做了一些异步的事情并且我想确保片段仍然附加到活动时(例如检查是否 isAdded developer.android.com/reference/android/app/…)。但是,如果您在链接页面的中端滚动,您会发现如何协调两个“不同”的生命周期。 抱歉,我没明白你在最后一行中所说的内容。【参考方案5】:我认为你应该使用Fragment
的onAttach(Activity)
方法。
我认为这应该可以帮助您避免所有这些 NPE。
【讨论】:
如果我使用它并在加载 UI 时删除了片段,但它仍然不会导致 NPE? @Rani 可以使用活动引用,然后检查它是否不为空,并确保在 onDetach 中将其标记为空以上是关于Android 片段 getActivity() = null的主要内容,如果未能解决你的问题,请参考以下文章
(Android Studio)不能在片段中使用 context/getActivity() [重复]