在执行AsyncTask时替换片段- getActivity()上的NullPointerException



我最近将我的activity转换为Fragments。

使用类似于tab - navigation的东西,当用户选择另一个tab时,片段被替换。片段填充后,我开始至少一个AsyncTask从互联网获取一些信息。然而,如果用户切换到另一个选项卡,就像doBackground-method从我的AsyncTask正在执行-片段是取代,因此我得到一个NullPointerException在标记行:

@Override
protected Object doInBackground(Object... params) {
  ...
  String tempjson = helper.SendPost(getResources().getText(R.string.apiid)); //ERROR: Fragment not attached
  ...
}
protected onPostExecute(Object result) {
  ...
  getActivity().getContentResolver() //NULLPOINTEREXCEPTION
  getView().findViewById(R.id.button) //NULL
  ...
}

getActivity()getResources()导致错误,因为我的Fragment被替换了。

我尝试过的事情:

  • 在我的AsyncTask上调用取消方法(不会修复第一个错误,也不会修复第二个错误,如果片段被替换,而onPostExecute()被执行)
  • 检查getActivity()是否为null或调用this.isDetached()(不是真正的修复,我需要检查它每当我调用getActivity()等)

所以我的问题是:什么是最好的摆脱这些AsyncTask问题?我在使用Activities时没有遇到这些问题,因为它们不会在选项卡更改时被"杀死"/分离(这会导致更高的内存使用-这就是我喜欢切换到Fragments的原因)

由于AsyncTask在后台运行,您的片段可能会在完成时脱离其父活动。正如你所发现的,你可以使用isDetached()来检查。这没有什么问题,你不必每次都检查,只需要考虑片段和活动的生命周期。

其他两个选择:

  • 使用加载器,它们可以更好地处理片段
  • 移动你的AsyncTask加载到父活动,并使用接口从片段解耦。该活动将知道片段是否存在,并相应地采取行动(如果片段消失,可能会丢弃结果)。

今天我遇到了同样的问题:当我改变fragment被显示,如果AsyncTask还没有完成,它试图访问view填充它与一些更多的元素,它会返回一个NullPointerException

我解决了重写片段生命周期的一个方法:onDetach()的问题。这个方法在fragmentactivity分离之前被调用。

你需要做的是在AsyncTask上调用cancel()方法。这将停止任务执行,避免NullPointerExecption

以下是onDetach()的示例:

@Override
public void onDetach() {
    super.onDetach();
    task.cancel(true);
}

查看此页面以获取有关fragment生命周期的更多信息:http://developer.android.com/reference/android/app/Fragment.html#Lifecycle这个可以查看更多关于取消任务的信息:http://developer.android.com/reference/android/os/AsyncTask.html

您是否尝试在您的片段类的onCreate()函数中调用setRetainInstance(true); ?

最新更新