IllegalStateException: This operation cannot be performed after onSaveInstanceState using ViewPager

Keywords: Java Android Fragment Session

I get user reports from apps on the market, but the following exceptions occur:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)
at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)
at android.app.Activity.onBackPressed(Activity.java:2066)
at android.app.Activity.onKeyUp(Activity.java:2044)
at android.view.KeyEvent.dispatch(KeyEvent.java:2529)
at android.app.Activity.dispatchKeyEvent(Activity.java:2274)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.widget.TabHost.dispatchKeyEvent(TabHost.java:297)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2880)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2853)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2028)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4028)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)

Obviously, it's about FragmentManager and I don't use it.The stacktrace does not show any of my own classes, so I don't know where this exception is and how to prevent it.

As a record: I have a tabhost, and in each tab, an Activity Group switches between activities.

#1st floor

please Ad locum Check my answer.Basically I just need:

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

Do not call super() on the saveInstanceState method.That's too bad...

This is a known in the support package error .

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

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

Finally, you can use the appropriate solution (as shown in the note):

transaction.commitAllowingStateLoss();

Add or execute a FragmentTransaction that results in Exception.

#2nd floor

This is another way to solve this problem.

With the private member variable, you can set the returned data as intent and then process it in super.onResume(); later.

Like this:

private Intent mOnActivityResultIntent = null; 

@Override
protected void onResume() {
    super.onResume();
    if(mOnActivityResultIntent != null){
        ... do things ...
        mOnActivityResultIntent = null;
    }
 }

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
    if(data != null){
        mOnActivityResultIntent = data;
    }
}

#3rd floor

Short and effective solutions:

Follow simple steps

Pace

Step 1: Override the onSaveInstanceState status in each fragment.And delete the super method from it.

 @Override
public void onSaveInstanceState( Bundle outState ) {

}  

Step 2: Use fragmentTransaction.commitAllowingStateLoss();

Instead of fragmentTransaction.commit(); fragments operate.

#4th floor

This exception occurs when I press the Back button to cancel the intent selector in the map snippet activity.I solved this problem by replacing onResume (the code in which I initialized the fragment) with onstart (), and the application worked correctly.Hopefully it will help.

#5th floor

There are many similar error message related issues.Check the second line of this particular stack trace.This exception is particularly relevant to the call to FragmentManagerImpl.popBackStackImmediate.

If session state is saved, this method call (such as popBackStack) will always fail with IllegalStateException.Check source.You cannot prevent the exception from being thrown.

  • Deleting the call to super.onSaveInstanceState would be useless.
  • Creating fragments using commitAllowingStateLoss will not help.

This is how I look at the problem:

  • There is a form with a submit button.
  • After clicking the button, a dialog box is created and the asynchronous process begins.
  • The user clicks the primary key to call onSaveInstanceState before processing is complete.
  • The process is complete, the callback is made, and the popBackStackImmediate is attempted.
  • IllegalStateException .

This is what I did to solve the problem:

Since it is not possible to avoid IllegalStateException in a callback, capture and 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 prevent the application from crashing.Now, however, users will restore the application and find that they have not pressed the button they think they have pressed at all (they think).Form fragments are still displayed!

To solve this problem, when you create a dialog box, set some states to indicate that the process has started.

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

Save this status in the bundle.

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

Don't forget to load onViewCreated again

Then, on recovery, roll back the fragment if you have previously attempted to commit.This prevents users from returning uncommitted forms.

@Override
public 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;
    }
}

Posted by cosmo7 on Wed, 22 Jan 2020 22:27:36 -0800