我最近将我的活动转换为碎片。
使用类似于Tab-Navigation的内容,当用户选择另一个选项卡时,会替换片段。
填充片段后,我启动至少一个AsyncTask以从Internet获取一些信息。但是 - 如果用户切换到另一个选项卡,就像我的AsyncTask中的doBackground方法正在执行一样 - 片段被替换,因此我在标记的行中得到NullPointerException
:< / p>
@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()
会导致错误,因为我的片段已被替换。
我尝试过的事情:
onPostExecute()
时替换片段,则不会修复第一个错误,也不会修复第二个错误)getActivity()
是null
还是致电this.isDetached()
(不是真正的解决方案,每当我致电getActivity()
时我都需要检查一下等等)所以我的问题是:摆脱这些AsyncTask问题最好的是什么?我没有使用活动这些问题,因为它们没有在标签更改时被“杀死”/分离(这导致更高的内存使用量 - 我之所以想切换到碎片的原因)
答案 0 :(得分:18)
由于AsyncTask
在后台运行,因此您的片段在完成时可能会与其父活动分离。如您所知,您可以使用isDetached()
进行检查。这没有什么不对,你不必每次都检查,只考虑片段和活动生命周期。
另外两种选择:
答案 1 :(得分:4)
今天我遇到了同样的问题:如果fragment
尚未完成,我更改了显示的AsyncTask
,并尝试访问view
以填充它更多元素,它将返回NullPointerException
。
我解决了覆盖片段生命周期的一种方法的问题:onDetach()
。在fragment
与activity
分离之前的那一刻调用此方法。
您需要做的是在cancel()
上调用AsyncTask
方法。这将阻止任务执行,避免NullPointerExecption
。
以下是onDetach()
的示例:
@Override
public void onDetach() {
super.onDetach();
task.cancel(true);
}
检查此页面以获取有关片段生命周期的更多信息: http://developer.android.com/reference/android/app/Fragment.html#Lifecycle 这是为了查看有关取消任务的更多信息: http://developer.android.com/reference/android/os/AsyncTask.html
答案 2 :(得分:-1)
您是否尝试在片段类的setRetainInstance(true);
函数中调用onCreate()
?