Search code examples
androidandroid-fragmentsfragmentmanagerandroid-savedstateonsaveinstancestate

Checking if state is saved before committing a FragmentTransaction


I sometimes see the following stacktrace for a commit that can happen when the user isn't looking at the activity (after state's been saved):

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)

Looking at the Android source, this makes total sense:

private void checkStateLoss() {
        if (mStateSaved) {
            throw new IllegalStateException(
                    "Can not perform this action after onSaveInstanceState");
        }
        if (mNoTransactionsBecause != null) {
            throw new IllegalStateException(
                    "Can not perform this action inside of " + mNoTransactionsBecause);
        }
 }

Now, I wonder if there is any way (besides storing a class variable in on(Save/Restore)InstanceState) to check if a fragment is going to be committed in an undesirable state, this way I can store the transaction for later and make the commit at the appropriate time.


Solution

  • Since you did not attach any example code, all i can guess is that you're using "wrong" method when committing transaction.

    so, instead of using FragmentTransaction.commit(), you should use FragmentTransaction.commitAllowingStateLoss().

    Also, there are reports and workarounds about this issue (or rather change in API behavior) in this google blog post.