我在Activity onCreate()方法中调用popBackStack(),但是我得到了异常:
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)
我理解解决此异常的一种方法是,如果您对UI和最终用户的影响没有问题,那就是调用commitAllowingStateLoss。
问题是,popBackStack没有提交调用。有没有其他方法可以调用popBackStack并允许状态丢失?
我应该说,我在onPostResume中执行此操作并获得此异常。
答案 0 :(得分:2)
经过大量研究后,我得出的结论是,当Activity恢复时,不可能在Android上操纵片段。根据上面提到的博客文章,我尝试使用onPostResume()和onResumeFragments()来从backstack中弹出片段,并且在发布到生产时都会导致间歇性崩溃。
这个现实的缺点是,例如,如果您想要显示级别片段的结尾,然后是插页式广告,接着是下一级别(作为级别片段末尾的不同片段),那么它不可能使用碎片。
就我个人而言,我从我的应用程序中删除了所有片段。我一直在使用布局,因为在XML中编辑UI很有用,但Fragment生命周期在当前状态下是不可用的,所以我推出了自己的"片段"子系统,但更好,因为它可以从Activities onResume操作。
我希望有一天谷歌会解决这个问题,因为它让Android开发真的很不愉快。无论如何,如果有人需要使用片段,但不喜欢你常常会得到的典型onSaveInstanceState异常,这里是我的游戏屏幕"实现(它就像一个片段,只有更好)
/**
* 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);
}
}
答案 1 :(得分:0)
我从此博客http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html
获得了以下内容如果commit()
在任何可以在恢复活动状态之前调用的Activity回调中,则可能抛出此错误。
所以popBackStack()
最好的地方是onResumeFragments()
回调
popBackStack()
内部调用了commit()
,因为它的作用只是反转了后台的FragmentTransaction
。