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】:

我认为你应该使用FragmentonAttach(Activity) 方法。

我认为这应该可以帮助您避免所有这些 NPE。

【讨论】:

如果我使用它并在加载 UI 时删除了片段,但它仍然不会导致 NPE? @Rani 可以使用活动引用,然后检查它是否不为空,并确保在 onDetach 中将其标记为空

以上是关于Android 片段 getActivity() = null的主要内容,如果未能解决你的问题,请参考以下文章

(Android Studio)不能在片段中使用 context/getActivity() [重复]

Android (安卓) getContext 和 getActivity的区别

安卓。片段 getActivity() 有时返回 null

片段 getActivity 不起作用

getActivity() 在片段上返回 null?

方向更改后片段中的 getActivity() 为空