IllegalStateException: Can not perform this action after onSaveInstanceState with ViewPager IllegalStateException: Can not perform this action after onSaveInstanceState with ViewPager android android

IllegalStateException: Can not perform this action after onSaveInstanceState with ViewPager


Please check my answer here. Basically I just had to :

@Overrideprotected void onSaveInstanceState(Bundle outState) {    //No call for super(). Bug on API Level > 11.}

Don't make the call to super() on the saveInstanceState method. This was messing things up...

This is a known bug in the support package.

If you need to save the instance and add something to your outState Bundle you can use the following:

@Overrideprotected void onSaveInstanceState(Bundle outState) {    outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");    super.onSaveInstanceState(outState);}

In the end the proper solution was (as seen in the comments) to use :

transaction.commitAllowingStateLoss();

when adding or performing the FragmentTransaction that was causing the Exception.


There are many related problems with a similar error message. Check the second line of this particular stack trace. This exception is specifically related to the call to FragmentManagerImpl.popBackStackImmediate.

This method call, like popBackStack, will always fail with IllegalStateException if the session state has already been saved. Check the source. There is nothing you can do to stop this exception being thrown.

  • Removing the call to super.onSaveInstanceState will not help.
  • Creating the Fragment with commitAllowingStateLoss will not help.

Here's how I observed the problem:

  • There's a form with a submit button.
  • When the button is clicked a dialog is created and an async process starts.
  • The user clicks the home key before the process is finished - onSaveInstanceState is called.
  • The process completes, a callback is made and popBackStackImmediate is attempted.
  • IllegalStateException is thrown.

Here's what I did to solve it:

As it is not possible to avoid the IllegalStateException in the callback, catch & ignore it.

try {    activity.getSupportFragmentManager().popBackStackImmediate(name);} catch (IllegalStateException ignored) {    // There's no way to avoid getting this if saveInstanceState has already been called.}

This is enough to stop the app from crashing. But now the user will restore the app and see that the button they thought they'd pressed hasn't been pressed at all (they think). The form fragment is still showing!

To fix this, when the dialog is created, make some state to indicate the process has started.

progressDialog.show(fragmentManager, TAG);submitPressed = true;

And save this state in the bundle.

@Overridepublic void onSaveInstanceState(Bundle outState) {    ...    outState.putBoolean(SUBMIT_PRESSED, submitPressed);}

Don't forget to load it back again in onViewCreated

Then, when resuming, rollback the fragments if submit was previously attempted. This prevents the user from coming back to what seems like an un-submitted form.

@Overridepublic void onResume() {    super.onResume();    if (submitPressed) {        // no need to try-catch this, because we are not in a callback        activity.getSupportFragmentManager().popBackStackImmediate(name);        submitPressed = false;    }}


Check if the activity isFinishing() before showing the fragment and pay attention to commitAllowingStateLoss().

Example:

if(!isFinishing()) {FragmentManager fm = getSupportFragmentManager();            FragmentTransaction ft = fm.beginTransaction();            DummyFragment dummyFragment = DummyFragment.newInstance();            ft.add(R.id.dummy_fragment_layout, dummyFragment);            ft.commitAllowingStateLoss();}