我在我的应用程序中使用片段。使用它们时非常常见的问题是使用getActivity()时的NPE。我知道我们可以通过每次检查getActivity() != null
或检查片段isAdded()
来解决它。
在我的一个课程中,我在60多个地方获得了活动的背景。检查getActivity()是否为null或者片段是否仍然添加到所有位置的活动中会使代码变得丑陋,更大且不可维护。有没有其他方法来处理这个? 当从活动中删除片段时,甚至可以销毁片段(并在删除时停止它所做的任何工作)?
答案 0 :(得分:11)
根据我的经验,大多数返回null的getActivity()都在异步回调中。
例如,您的片段触发AsyncTask,然后在后台作业完成之前被删除,然后当后台作业完成并在onPostExecute()中调用getActivity()时,它将获得null,因为片段已经脱离活动。
我的解决方案:
1.在每个异步回调开始时检查getActivity()== null,如果是这种情况,则只是中止该方法。
2.取消onDetach()中的异步作业。
我认为这比在onAttach()中保存活动实例更好的解决方案,因为自从你的片段被删除后,为什么要干掉回调中留下的所有作业(在大多数情况下是UI代码)?
答案 1 :(得分:4)
getActivity将在方法中重新启动 - onActivityCreated()。
因此,在onActivityCreated()之后调用getActivity()更安全(根据片段http://developer.android.com/guide/components/fragments.html的生命周期) - 例如在onStart()中 - 在这种情况下它将永远不会为空 - 无需做无用检查像isAdded和getActivity!= null。
P.S。如果我们使用该解决方案:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
动态性永远不会为空 - 但后来在方法onActivityCreated()中,getActivity()与mActivity的不同之处。 我的意见 - 确保我们可以将整个活动保存在变量中,但是更安全的是遵循android片段生命周期工作流程并在onActivityCreated()之后立即获取活动
答案 2 :(得分:0)
我认为你应该使用Fragment
的{{1}}方法。
我认为这应该可以帮助你避免所有这些NPE。
答案 3 :(得分:0)
我的解决方案是覆盖BaseActivity中的onSaveInstanceState方法:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//solution of fragment.getActivity() is null
outState.remove("android:support:fragments");
}
答案 4 :(得分:-1)
我没有找到解决方法,也许是因为如果你考虑lifecycle of a fragment,你应该能够在检查空值时理解。