popBackStack和commitAllowingStateLoss

我在Activity的onCreate()方法中调用popBackStack(),但是我得到了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) 

我明白,解决这个exception的一种方法,只要你对UI和最终用户的影响是可以的,就是调用commitAllowingStateLoss。

问题是,用popBackStack没有提交调用。 有没有其他的方式来调用popBackStack并允许状态丢失?

我应该说,我正在onPostResume做这个,得到这个exception。

Solutions Collecting From Web of "popBackStack和commitAllowingStateLoss"

经过大量的研究,我得出的结论是,当Activity被恢复时,不可能在Android上操纵片段。 按照上面提到的博客文章,我已经尝试过onPostResume()和onResumeFragments()从后台堆栈中popup片段,并且在发布到产品时都会导致间歇性崩溃。

这个现实的缺点是,如果你想,例如,显示级别片段的结尾,然后是插页式广告,然后是下一级别(作为到片段末尾的不同片段),则不可能使用片段。

对于我个人的情况,我从应用程序中删除了所有的片段。 我继续使用布局,因为在XML中编辑UI是有用的,但是Fragment的生命周期在当前状态下是不可用的,所以我推出了自己的“片段”子系统,但更好,因为它可以从Activity onResume中操作。

我希望有一天Google能够解决这个问题,因为它让Android的开发变得非常不愉快。 无论如何,如果有人需要使用片段,但不喜欢你一定会得到的典型onSaveInstanceStateexception,这里是我的“GameScreen”实现(它就像一个片段,只是更好)

 /** * 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); } } 

我从下面的博客http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

如果commit()在任何可以在活动状态恢复之前调用的Activitycallback中,则可能会抛出此错误。 所以做popBackStack()最好的地方是onResumeFragments()callback

popBackStack()有一个内部调用的commit() ,它只是颠倒了backstack中的最后一个FragmentTransaction