android compatibility package - fragment ... not attached to Activity

Viewed 25667

Hello, I'm facing this problem : I'm using Compatibility package to use fragment in android application (min SDK 2.1).

An random exception occurs on fragment sometimes and I can't figure out why. This is the stack trace I receive:

java.lang.IllegalStateException: Fragment FeedListFragment{438a54e8} not attached to Activity
    at android.support.v4.app.Fragment.getLoaderManager(Fragment.java:715)
    at com.myappli.ui.FeedListFragment.refreshUpdateDate(FeedListFragment.java:283)
    at com.myappli.ui.phone.FeedListActivity.onReceiveResult(FeedListActivity.java:277)
    at com.myappli.data.rssplayer.service.KTDetachableResultReceiver.onReceiveResult(KTDetachableResultReceiver.java:55)
    at android.os.ResultReceiver$MyRunnable.run(ResultReceiver.java:43)
    at android.os.Handler.handleCallback(Handler.java:587)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:4425)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
    at dalvik.system.NativeStart.main(Native Method)

Here is the corresponding code I'm calling in the Fragment class:

public class FeedListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>, FeedListCursorAdapterListener {

...
    public void refreshUpdateDate() {
    getLoaderManager().restartLoader(LAST_UPDATE_CURSOR_ID, null, this);
    }
...
}

Here is the code of the activity that calls the fragment:

private FeedListFragment mCursorLoaderListFg;

if (!isFinishing()) {
    mCursorLoaderListFg.refreshUpdateDate();
    mCursorLoaderListFg.refreshDisplay();
    mCursorLoaderListFg.hideLoadingArticles();
}

Here is the fragment source code for getLoaderManager():

/**
* Return the LoaderManager for this fragment, creating it if needed.
*/
public LoaderManager getLoaderManager() {
    if (mLoaderManager != null) {
        return mLoaderManager;
    }
    if (mActivity == null) {
        throw new IllegalStateException("Fragment " + this + " not attached to Activity");
    }
    mCheckedForLoaderManager = true;
    mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, true);
    return mLoaderManager;
}

Here are the steps of the application before crash:

  1. The activity calls methods in background.
  2. Callback methods are called on the activity
  3. In this callback method, the activity calls the fragment
  4. The fragment tries to launch some methods (like getLoadManager()) that need activity.
  5. The fragment is not attached anymore to the activity => crash

We tried two fixes:

  • test on activity to check if the activity is finishing (like the code above)
  • test on the fragment with the method isDetached.

Thanks for your help!!!

Do not hesitate to ask me more information if I'm not clear.

4 Answers

I resolved this issue by changing my inner adapter class to static inner class.

private static class MessagesAdapter extends CursorAdapter {
...

I am not sure how to explain that but it's related to the fact that we should avoir using non static inner class as recommended here

Related