android 弹出回栈和提交允许状态丢失

5kgi1eie  于 2022-12-25  发布在  Android
关注(0)|答案(3)|浏览(111)

我在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)

我知道,解决此异常的一种方法是调用commitAllowingStateLoss,前提是您可以接受对UI和最终用户的影响。
问题是,popBackStack没有提交调用,是否有其他方法调用popBackStack并允许状态丢失?
我应该说,我在onPostResume中执行此操作并得到此异常。

mzsu5hc0

mzsu5hc01#

经过大量研究,我得出结论,当Activity恢复时,不可能在Android上操作片段。根据前面提到的博客文章,我曾尝试使用onPostResume()和onResumeFragments()从后栈弹出片段,但这两种方法在发布到生产环境时都会导致间歇性崩溃。
这种现实的缺点是,如果你想,例如,显示一个级别结束片段,然后是一个中间广告,然后是下一个级别(作为一个不同的片段到级别结束片段),那么它是不可能使用片段。
对于我个人的情况,我从我的应用程序中删除了所有的片段。我继续使用布局,因为在XML中编辑UI是有用的,但片段生命周期在其当前状态下不可用,所以我推出了自己的“片段”子系统,但更好的是,因为它可以从Activities onResume进行操作。
我希望有一天Google能解决这个问题,因为它让Android开发变得非常不愉快。无论如何,如果有人需要使用片段,但不喜欢你总是会得到的典型的onSaveInstanceState异常,下面是我的“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);
    }
}
ivqmmu1c

ivqmmu1c2#

我从这个博客http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html得到下面
如果commit()位于任何活动回调中,而该活动回调可能在恢复活动状态之前调用,则可能引发此错误。因此,执行popBackStack()的最佳位置是onResumeFragments()回调
popBackStack()确实有一个内部调用的commit(),因为它所做的只是反转反向堆栈中的最后一个FragmentTransaction

5cg8jx4n

5cg8jx4n3#

检查此方法可能会有所帮助:

popBackStackImmediate()

这个方法的优点是它返回一个布尔值来指示返回栈的成功,至少你可以尝试捕捉这个方法来防止异常,并找出异常发生的原因。
看看这份指南:
https://developer.android.com/reference/android/app/FragmentManager.html#popBackStack()

相关问题