I recently converted my Activities to Fragments.
Using something similar to Tab-Navigation the fragments are replaced when the user selects another tab.
After the fragment is populated I start at least one AsyncTask to get some information from the internet. However - if the user switches to another tab just as the doBackground-method from my AsyncTask is being executed - the fragment is replaced and thus I am getting a NullPointerException
in the marked lines:
@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()
and getResources()
causes an error because my Fragment is replaced.
Things I've tried:
onPostExecute()
is executed)getActivity()
is null
or calling this.isDetached()
(not a real fix and I'd need to check it whenever I call getActivity()
and so on)So my question is: what would be the best to get rid of these AsyncTask problems? I did not have these problems using Activities as they weren't "killed" / detached on tab change (which resulted in higher memory usage - the reason why I like to switch to Fragments)
Since AsyncTask
is running in the background, your fragment may become detached from its parent activity by the time it finishes. As you've found out, you can use isDetached()
to check. There's nothing wrong with that, and you don't have to check every time, just consider the fragment and activity life cycles.
Two other alternatives:
Today I've faced the same problem: when I changed the fragment
being displayed if the AsyncTask
has not finished yet, and it tries to access the view
to populate it with some more elements, it would return a NullPointerException
.
I solved the problem overriding one method of the fragments lifecycle: onDetach()
. This method is called in the moment before the fragment
is detached from the activity
.
What you need to do is to call the cancel()
method on your AsyncTask
. This will stop the task execution avoid the NullPointerExecption
.
Here's a sample of onDetach()
:
@Override
public void onDetach() {
super.onDetach();
task.cancel(true);
}
Check this page to get more information about fragments lifecycle: http://developer.android.com/reference/android/app/Fragment.html#Lifecycle And this to view more about Cancelling a task: http://developer.android.com/reference/android/os/AsyncTask.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With