Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/199.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android OnBackbackChanged()中的调用时,SDK 25.1.0在CommitNow上崩溃。谷歌Bug?_Android_Android Fragments - Fatal编程技术网

Android OnBackbackChanged()中的调用时,SDK 25.1.0在CommitNow上崩溃。谷歌Bug?

Android OnBackbackChanged()中的调用时,SDK 25.1.0在CommitNow上崩溃。谷歌Bug?,android,android-fragments,Android,Android Fragments,我有一个活动,有两个片段FragmentMainOne和FragmentMainTwo,只要调用onbackbackbackchanged(),它们就会交换 public class MainActivity extends AppCompatActivity { private int count = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCr

我有一个活动,有两个片段
FragmentMainOne
FragmentMainTwo
,只要调用
onbackbackbackchanged()
,它们就会交换

public class MainActivity extends AppCompatActivity {

    private int count = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        loadFragment();

        getSupportFragmentManager().addOnBackStackChangedListener(
                new FragmentManager.OnBackStackChangedListener() {
                    @Override
                    public void onBackStackChanged() {
                        if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
                            loadFragment();
                        }
                    }
                });
    }

    public void loadSubFragment() {
        getSupportFragmentManager().beginTransaction().replace(R.id.view_container,
                new FragmentSubOne(), FragmentSubOne.TAG).addToBackStack(FragmentSubOne.TAG).commit();
    }

    public void loadFragment() {
        count++;
        if (count % 2 == 1) {
            getSupportFragmentManager().beginTransaction().replace(R.id.view_container,
                    new FragmentMainOne(), FragmentMainOne.TAG).commitNow();
        } else {
            getSupportFragmentManager().beginTransaction().replace(R.id.view_container,
                    new FragmentMainTwo(), FragmentMainTwo.TAG).commitNow();
        }
    }
}
这些代码在升级到SDK 25.1.0之前运行良好。(即25.0.0及更早版本中的OK)

升级到SDK 25.1.0后,在
onbackbackbackchanged()
时,它将在
commitNow()
上崩溃

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.elyeproj.commitissue, PID: 3876
              java.lang.IllegalStateException: FragmentManager is already executing transactions
                  at android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:1946)
                  at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1965)
                  at android.support.v4.app.BackStackRecord.commitNow(BackStackRecord.java:614)
                  at com.elyeproj.commitissue.MainActivity.loadFragment(MainActivity.java:45)
                  at com.elyeproj.commitissue.MainActivity$1.onBackStackChanged(MainActivity.java:27)
                  at android.support.v4.app.FragmentManagerImpl.reportBackStackChanged(FragmentManager.java:2409)
                  at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2157)
                  at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2092)
                  at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:822)
                  at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:775)
                  at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:178)
如果我将
commitNow()
切换到
commit()
,它也可以正常工作。这是最新SDK上的错误,还是我遗漏了什么

注意:完整的代码可能是复制问题的访问权限
(只需加载应用程序,单击“转到子片段”,然后单击“返回”…崩溃发生。)

调查后,这似乎是Support Library 25.1.0中引入的新约束

撞车发生在星期四

private void ensureExecReady(boolean allowStateLoss) {
    if (mExecutingActions) {
        throw new IllegalStateException("FragmentManager is already executing transactions");
    }
    // ... more codes
}
因此,有人将
mExecutingActions
设置为true

发现在25.1.0 FragmentManager类中,下面的代码是新的

private boolean popBackStackImmediate(String name, int id, int flags) {
    execPendingActions();
    ensureExecReady(true);

    boolean executePop = popBackStackState(mTmpRecords, mTmpIsPop, name, id, flags);
    if (executePop) {
        mExecutingActions = true;
        try {
            optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
        } finally {
            cleanupExec(); // setting mExecutingAction = false
        }
    }

    doPendingDeferredStart();
    return executePop;
}
当弹出片段堆栈时,它将
mExecutingActions
设置为true。这不是在25.1.0之前设置的。我认为这是一种明确的预防措施,以确保在提交另一个片段之前完成backbackback弹出

为了解决这个问题,只要我们
commit()
而不是
commitNow()


关于这个问题的更多说明,请参考

,我认为这很好,因为当调用
onbackbackchanged()
时,fragmentManager仍在处理事务,而您正试图在manager仍在处理事务时再处理一个事务。
commitNow()
与调用
executePendingTransactions()完全相同
提交后。所以只有两个选择,1。使用
commit()
2。使用
someView.Post(new Runnable(){})
将事务放入messageQueue。谢谢@AkshayBhat'AB。我已经找到了原因,也符合你的解释。我已经贴出了答案。