I call popBackStack() in Activity onCreate() method, however I am getting the exception:
Caused by java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
android.app.FragmentManagerImpl.checkStateLoss (FragmentManager.java:1428)
android.app.FragmentManagerImpl.enqueueAction (FragmentManager.java:1446)
android.app.FragmentManagerImpl.popBackStack (FragmentManager.java:572)
I understand that one way of solving this exception, provided you are OK with the effects on the UI and end user, is to call commitAllowingStateLoss.
The problem is, with popBackStack there is no commit call. Is there some other way to call popBackStack and allow state loss?
I should say, I am doing this in onPostResume and getting this exception.
public abstract void popBackStack () Pop the top state off the back stack. This function is asynchronous -- it enqueues the request to pop, but the action will not be performed until the application returns to its event loop.
commitAllowingStateLoss():A transaction can only be committed with this method prior to its containing activity saving its state. If the commit is attempted after that point, an exception will be thrown. This is because the state after the commit can be lost if the activity needs to be restored from its state.
commitAllowingStateLoss() Like commit() but allows the commit to be executed after an activity's state is saved.
popBackStack will just revert your last FragmentTransaction . If you use FragmentTransaction. add , popBackStack will just call FragmentTransacetion.
After much research I have come to the conclusion that it is not possible to manipulate fragments on Android when the Activity is resumed. I have tried, as per the mentioned blog post, onPostResume() and onResumeFragments() to pop fragments from the backstack, and both result in intermittent crashes when released to production.
The downside to this reality is that if you wanted to, for example, display an end of level fragment, followed by an interstitial advertisement, followed by the next level (as a different fragment to the end of level fragment) then it is not possible to use fragments.
For my personal situation, I removed all fragments from my application. I keep using layouts, because editing the UI in XML is useful, but the Fragment lifecycle is unusable in its current state so I rolled my own "fragment" subsystem, but better because it can be manipulated from the Activities onResume.
I hope that one day Google will fix this because it makes developing for Android really unpleasant. Anyway, if anyone needs to use fragments, but doesn't like the typical onSaveInstanceState exception that you will invariably get, here is my "GameScreen" implementation (it's like a fragment, only better)
/**
* GameScreen
*/
public class GameScreen {
private int id;
private View view;
private ViewGroup viewGroup;
protected MainActivity mainActivity;
public GameScreen(MainActivity mainActivity, int id) {
this.mainActivity = mainActivity;
this.id = id;
}
public void create(LayoutInflater layoutInflater, ViewGroup viewGroup) {
this.viewGroup = viewGroup;
view = layoutInflater.inflate(id, viewGroup, false);
viewGroup.addView(view);
}
public void show() {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View v = viewGroup.getChildAt(i);
if (v != view) {
v.setVisibility(View.INVISIBLE);
}
}
view.setVisibility(View.VISIBLE);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With