popBackStack和commitAllowingStateLoss

时间:2017-02-28 02:14:29

标签: android

我在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中执行此操作并获得此异常。

2 个答案:

答案 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