javaandroidandroid-asynctaskfragmentandroid-loadermanager

illegalStateException in onLoadFinishe


java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1886) at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1905) at android.app.BackStackRecord.commitInternal(BackStackRecord.java:688) at android.app.BackStackRecord.commit(BackStackRecord.java:646) at android.app.DialogFragment.dismissInternal(DialogFragment.java:312) at android.app.DialogFragment.dismiss(DialogFragment.java:278)

Why I am getting this crash in play store console for some of my users. This is not device or OS specific.

I am not doing any UI related transaction in onLoadFinished. I am executing ABCAsyncTask, and in onPostExecute of it, i am calling pausehandler to execute the UI.

Additionally, As I am using two cursors, so onLoadFinished in called twice here.

@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
    if (cursor == null) {
        Log.e(LOG_TAG, "cursor is null");
        return;
    }


    (new ABCAsyncTask(this, cursorLoader, cursor)).execute();
}

ABCAsyncTask ->

 onPostExecute() {
    LoadItemPauseHandlerObject loadItemPauseHandlerObject = new LoadItemPauseHandlerObject ();
    Message responseMessage = new Message();
    responseMessage.what = 1; // some int
    responseMessage.obj = loadItemPauseHandlerObject;
    pauseHandler.sendMessage(responseMessage);
    }

In android OS source code:

void callOnLoadFinished(Loader<Object> loader, Object data) {
if (mCallbacks != null) {
String lastBecause = null;
if (mHost != null) {
lastBecause = mHost.mFragmentManager.mNoTransactionsBecause;
                    mHost.mFragmentManager.mNoTransactionsBecause = "onLoadFinished";
}
try {
if (DEBUG) Log.v(TAG, "  onLoadFinished in " + loader + ": "
+ loader.dataToString(data));
                    mCallbacks.onLoadFinished(loader, data);
                } finally {
if (mHost != null) {
mHost.mFragmentManager.mNoTransactionsBecause = lastBecause;
}
}
mDeliveredData = true;
}
}

since finally {} block will always be executed synchronously after try {} block in the main thread, and in onLoadFinished() i am not doing any fragment transaction directly, so, mNoTransactionsBecause should reset to lastBecause then why this crash is coming for some of my users?

I am using :

android.app.LoaderManager android.app.Activity android.app.Fragment


Solution

  • Try adding check

    isAdded()
    

    in your handleMessage() method of your handler possibly it would be in your Fragment. Let me know if you have further doubt