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; } }