最近在做一个项目需要在一个界面中嵌套多个Fragment,但是在Fragment之间切换的时候出现了一个bug很棘手。话不多说直接贴上bug详情如下:
我们可以知道这个bug是Fragment之前切换的时候调用commitAllowingStateLoss()产生的,我们来看看commitAllowingStateLoss()的源码
继续往下看commitInternal(true)源码
我们发现最终会走到enqueueAction()这个方法,我们继续看源码:
哈哈,这个时候有没有发现眼前一亮啊,终于找到bug问题的所在了吧!但是有一个问题是不是没弄明白呢?为那就是为啥mDestroyed为true或者mHost==null,别急我们继续往下查找,我们首先要看一下给mDestroyed赋值和mHost置空的地方,结果皇天不负有心人啊!我们发现在FragmentManager里面有一个方法dispatchDestroy()里面有队mDestroyed和mhost做了处理。
接下来我们就要查看为什么回调用dispatchDestroy()这个方法。我们都知道一个Activity销毁掉会走onDestroy()这个方法,如下:
看到这里是不是就很清晰了原来是调用commitAllowingStateLoss()的时候activity已经销毁掉了,至于activity为啥会销毁那就要看一下原因了,如果没找到原因那么可以在执行commitAllowingStateLoss()时做一个activity非空的判断。至此一个复杂的bug被处理掉了。