Fragment MyFragment not attached to Activity Fragment MyFragment not attached to Activity android android

Fragment MyFragment not attached to Activity


I've found the very simple answer: isAdded():

Return true if the fragment is currently added to its activity.

@Overrideprotected void onPostExecute(Void result){    if(isAdded()){        getResources().getString(R.string.app_name);    }}

To avoid onPostExecute from being called when the Fragment is not attached to the Activity is to cancel the AsyncTask when pausing or stopping the Fragment. Then isAdded() would not be necessary anymore. However, it is advisable to keep this check in place.


The problem is that you are trying to access resources (in this case, strings) using getResources().getString(), which will try to get the resources from the Activity. See this source code of the Fragment class:

 /**  * Return <code>getActivity().getResources()</code>.  */ final public Resources getResources() {     if (mHost == null) {         throw new IllegalStateException("Fragment " + this + " not attached to Activity");     }     return mHost.getContext().getResources(); }

mHost is the object that holds your Activity.

Because the Activity might not be attached, your getResources() call will throw an Exception.

The accepted solution IMHO is not the way to go as you are just hiding the problem. The correct way is just to get the resources from somewhere else that is always guaranteed to exist, like the application context:

youApplicationObject.getResources().getString(...)


I've faced two different scenarios here:

1) When I want the asynchronous task to finish anyway: imagine my onPostExecute does store data received and then call a listener to update views so, to be more efficient, I want the task to finish anyway so I have the data ready when user cames back. In this case I usually do this:

@Overrideprotected void onPostExecute(void result) {    // do whatever you do to save data    if (this.getView() != null) {        // update views    }}

2) When I want the asynchronous task only to finish when views can be updated: the case you're proposing here, the task only updates the views, no data storage needed, so it has no clue for the task to finish if views are not longer being showed. I do this:

@Overrideprotected void onStop() {    // notice here that I keep a reference to the task being executed as a class member:    if (this.myTask != null && this.myTask.getStatus() == Status.RUNNING) this.myTask.cancel(true);    super.onStop();}

I've found no problem with this, although I also use a (maybe) more complex way that includes launching tasks from the activity instead of the fragments.

Wish this helps someone! :)