Fragment事务提交遇到的错误(引子)

近期准备开源一个Fragment相关的开源项目,本来是想简单调用Fragment的Api来封装一个库可以让使用Fragment更简单,但是在库的封装过程中发现遇到的有些Bug不看源码是无法解决的,所以准备先放下手头的开源过程,对Fragment的源码进行解析。

为了在节省文章篇幅,我们在下文中用到FragmentManager简称为FMFragmentTransaction称为FT


让我产生分析源码念头的导火索

场景:有两个Fragment,暂且称为AFragmentBFragment,二者均要在Activity中进行显示。
1、对AFragment进行了addshow的事物提交操作,AFragment正常显示
2、点击AFragment中的按钮,对BFragment进行add的事物提交,并对AFragment进行remove的事物提交。
3、然后通过AFragmentTAGFM中查找这个Fragment,进行show操作的事物提交。

上面的流程没毛病吧,(不用考虑Activity的状态,可以保证每次事物正常提交),但是结果给了我一个suprise,通过FM#findFragmentByTag找不到AFragment,吓得我赶紧打了个断点,依次执行:FT#addFT#showFT#commit并在commit方法之后打了一个断点。

AFragment进行添加之后的FM状态截图

懵逼!!!!我们明明已经addFragment,并且提交了事物,但是FM中并没有添加过的Fragment对象???但是,怎么在之前添加的时候没问题,难道Fragment的事物提交之后FM并不是立即处理的???

换个场景再次尝试

Activity在进入的时候直接对AFragment进行add、show的事物提交(第一次提交),然后在点击按钮的时候对BFragment进行add的事物提交(第二次提交),在第二次提交的后面打上断点,看看FM的状态。

第二次提交后的FM状态截图

?????FM中出现了一个Fragment(这个TestFragment就是我们的AFragment),什么情况??我的BFragment去哪儿了???被你吃了吗??在此之后又进行了几次尝试,发现有时候可以出现BFragment,但大多数都和上图情况一样,这更加验证了我之前的猜想,Fragment事物不是立即执行的


这一发现让我很难受,因为我的Fragment开源框架中的事物提交是通过保存的队列顺序执行的,要是每次事物提交之后真正执行时机不明确的话是会影响我下次事物提交的!!!算了,放下手头的开源,准备先对Fragment的源码解析一波再继续搬砖!!!

源码分析及解决方案

Fragment事务提交源码分析