Fatal Exception: java.lang.IllegalStateException
FragmentManager is already executing transactions
androidx.fragment.app.FragmentManager.ensureExecReady (FragmentManager.java:4)
androidx.fragment.app.FragmentManager.execSingleAction (FragmentManager.java:11)
androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss (BackStackRecord.java:2)
查看源码发现发生这个异常是因为FragmentManager一次操作未结束时又进行了下一次操作。(通过mExecutingActions这个变量进行判定的)
说明有两次Fragment操作很接近,并且因为是commitNowAllowingStateLoss,代码是同步的且所有相关操作都在主线程,不存在多线程。所以一般应该是发生了嵌套行为。即:
mExecutingActions =true;
xxx();
mExecutingActions =false;
查看异常上下文,发现是在“添加Fragment—》Fragment内部初始化相关组件失败—》回调到外部移除该Fragment“,且移除Fragment的方法使用的是runOnUiThread,runOnUiThread里面判定了如果是主线程,则直接运行Runnable,此时是同步代码,发生了上方的同步行为触发该异常。
主要思路为通过异步的方式避免这种嵌套调用就行了
使用commitAllowingStateLoss代替commitNowAllowingStateLoss,因为commitNowAllowingStateLoss是同步,commitAllowingStateLoss是异步。
使用handler.post或者view.post替代runOnUiThread,实现异步。
需求:滑动变化页面,tab栏随之变化(很一般的常见需求了)
bug现象描述:(1)Fragment没有被创建和添加进viewPager,(2)有时候activity加载出来时crash,(3)有时候contain的Activity正常加载,试图滑动页面就crash
Log信息:
11-23 18:50:53.667 15943-15943/? E/AndroidRuntime: FATA
这是因为FragmentManager会在状态保存后保存事务的回退栈,所以如果在状态保存后提交一个事务,那么这个事务就不会被保存在回退栈中。这可能会导致应用在恢复状态时出现不一致的状态。: 这个方法允许在状态已经被保存后提交事务,即使这可能会导致状态丢失。它不会抛出状态丢失的异常,但如果在状态保存后提交事务,那么这个事务就不会被保存在回退栈中,可能会导致应用在恢复状态时出现不一致的状态。通常来说,你应该尽量避免在状态已经保存后提交事务,因为这可能会导致应用的用户界面状态与实际的应用状态不一致。
java.lang.IllegalStateException: FragmentManager is already executing transactions
at androidx.fragment.app.FragmentManagerImpl.ensureExecReady(FragmentManagerImpl.java:14)
at androidx.fragment.app.FragmentManagerImpl.execSingleAction(...
在Activity初始化FragmentTabHost的时候,传入了一个fragmentmanager,就是getFragmentManager拿到的,因为tabhost要交互的是第一层的fragment ,是直接和activity相交互的。而在Fragment1里嵌套的viewpager ,因为要交互的是嵌套的Fragment,所以需要拿到ChildFragmentManager才行。里面viewpager的setadapter的时候使用的是。在用viewpager+tablayout+
关于FragmentTransaction的各种提交方法: commit(),commitAllowingStateLoss(),commitNow()和commitNowAllowingStateLoss().
作者Bryan Herbst发了一个blog The many flavors of commit()讨论这几个方法的特点和用途.
下文是中文摘要.
FragmentTransactio...
java.lang.IllegalStateException: FragmentManager is already executing transactions
at android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:2006)
at android.support.v4.app.FragmentManagerImpl
Android 基础:Fragment 各种 Commit 使用注意事项和异常解析
Fragment进阶-commit使用细节及源码分析
Fragment的FragmentTransaction 的commit()和commitAllowingStateLoss()以及commitNow()和commitNowAllowingStateLoss()
commit(), commitNow()和co...
.beginTransaction()
.remove((Fragment) view)
.commitNowAllowingStateLoss();编译异常,提示找不到符号commitNowAllowingStateLoss() FragmentTransaction transa