FragmentManager is already executing transactions异常

错误日志

 java.lang.IllegalStateException: FragmentManager is already executing transactions
                                                    	at androidx.fragment.app.FragmentManager.ensureExecReady(FragmentManager.java:1931)
                                                    	at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1967)
                                                    	at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:311)
                                                    	at com.example.genework1.base.BaseActivity.addFragmentNow(BaseActivity.java:24)
                                                    	at com.example.genework1.activity.TestCommitActivity.openPage(TestCommitActivity.java:22)
                                                    	at com.example.genework1.fragment.TestFragment1.onViewCreated(TestFragment1.java:26)

触发场景

Activity继承了接口IAction,其方法中打开Fragment2

public class TestCommitActivity extends BaseActivity implements IAction {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_commit);
        addFragmentNow(R.id.content, new TestFragment1());
    }

    @Override
    public void openPage() {
        addFragmentNow(R.id.content, new TestFragment2());
    }
    
    protected final Fragment addFragmentNow(int id, Fragment fragment) {
        if (fragment == null)
            return null;
        if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.INITIALIZED)) {
            getSupportFragmentManager().beginTransaction().add(id, fragment).commitNowAllowingStateLoss();
            return fragment;
        }
        return null;
    }

}

Activity中添加了一个Fragment1,在Fragment1的onViewCreated方法中回调Activity中onPage方法打开界面Fragment2,发生错误。

原因分析

出现此问题的原因是FragmentManager的一次操作未结束时又触发了新的操作,而调用的方法又是commitNowAllowingStateLoss(),触发了如下方法:

    private void ensureExecReady(boolean allowStateLoss) {
        if (mExecutingActions) {
            throw new IllegalStateException("FragmentManager is already executing transactions");
        }

        if (mHost == null) {
            if (mDestroyed) {
                throw new IllegalStateException("FragmentManager has been destroyed");
            } else {
                throw new IllegalStateException("FragmentManager has not been attached to a host.");
            }
        }

        if (Looper.myLooper() != mHost.getHandler().getLooper()) {
            throw new IllegalStateException("Must be called from main thread of fragment host");
        }

        if (!allowStateLoss) {
            checkStateLoss();
        }

        if (mTmpRecords == null) {
            mTmpRecords = new ArrayList<>();
            mTmpIsPop = new ArrayList<>();
        }
        mExecutingActions = true;
        try {
            executePostponedTransaction(null, null);
        } finally {
            mExecutingActions = false;
        }
    }

上述代码中的变量mExecutingActions会在第一次执行时置为true,由于代码是同步的且所有的相关操作都在主线程,不存在多线程,所以在上次操作尚未结束时(mExecutingActions尚未置为false)再次调用此方法,就会抛出异常。

解决办法

通过异步的方式可以解决掉此问题。

推荐方法:使用为commitAllowingStateLoss()替换执行,commitAllowingStateLoss()方法为异步执行,可以规避掉此问题的出现。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值