fragment 相信基本上每个android developer都用过,但是知晓其原理 用的好的还是不多,今天就从源码的角度上来带着大家分析一下Fragment的源码,对fragment有了更深层次的认识以后相信
写出来的代码也会越来越好看。
首先,我们来看第一个流程,fragment是怎么加载到界面上的,借着这个流程分析,能读完绝大多数fragment的源码。
一般我们显示一个fragment的时候 喜欢如下这种做法:
这段代码相信大家都很熟悉了,我们就来一步步跟进去看看 ,2-5 执行结束以后 是怎么把fragment界面显示到手机屏幕上的。
上面 初步分析了getFragmentManager这个方法的由来。那继续看这个方法到底是返回的什么?
再进去看看 这个对象的begin方法返回的是什么
你看 所以begintranscation返回的最终就是backstackrecord对象了。
我们继续看看这个对象的操作
一直到这里 我们就知道,commit操作 最终执行的实际上是我们backstackrecord 这个类里的run方法。
到这里应该就差不多了,最终的线索就是 只要搞明白moveToState这个函数就可以了。
一直分析到这里,相信大家就对fragment的源码基础知识有一个不错的理解了,在这里 就简单总结一下 上面的分析:
1.Fragmentactivity 是具有支持fragment功能的最底层的activity。其他什么AppCompatActivity都是他的子类!
2.FragmentActivity主要负责就是生命周期的转发,比如onCreate onResume onDestroy等等,这就是为什么activity和fragment状态能统一的原因了!
当然了,分发的原因就是因为fragmentactivity源码里面持有一个fragmentController的实例!
3.其实将白了,fragmentController就是因为他自己有一个fragmenthostcallback,然后这个hostback还持有了fragmentmanger 所以这个controller 能分发activity的事件!
4.fragementhostcallback持有了activity的很多资源,context handler 是最主要的2个。fragmentmanger就是因为拿到了activty的这2个资源,所以才能和activty互相通信的!
5.fragmentmangerimple就是fragmentmanger的具体实现类。movetostate方法就是在这个里面实现的
6.FragmentTransition 也是个抽象类,他主要就是提供对外的接口函数的 add replace move 这种。BackStackRecord 就是它的具体实现类。还额外实现了runnable接口。
所以BackStackRecord 里面会有个run方法 这个run方法就是根据不同的操作(所谓操作就是OP.CMD的那个值) 来分发不同的事件,从而调用fragmentmanger的各种转换fragment生命周期的方法!
最后在说一下 fragment的 缓存和恢复机制吧。
然后我们看一下 当我们的activity onstop以后 会给fragment带来什么?
我们再考虑一下另外一个场景:
比如说 我们旋转了屏幕。并且
setRetainInstance 为true的时候
看看fragment是怎么处理的(为false的情况 就是fragment和activity一样了 activity怎么做fragment就怎么做 没什么好讲的必要。。)
最后再考虑一种场景,假设我们的宿主activity 在后台挂起的时候,因为内存不足 被系统杀掉了。fragment会发生什么?
其实也很简单啊,源码就不贴了,大家自己看,我说下简单的流程:
1.首先要明确 activity的onSaveInstanceState的方法,是在onPause以后 onStop以前调用的。
2.activty放到后台的时候会调用onstop方法,但是onSaveInstanceState是在这之前被调用的
3.所以实际上FragmentManager保存的那3个数组mActive、mAdded、mBackStack都被提前保存到FragmentManagerState里面了
4.等到activity重新回到前台 走oncreate的时候,会获得savedInstanceState这个实例,通过他去创建新的FragmentManager实例和新的fragment对象。
5.此时不管fragment是否setRetainInstance(true),Fragment实例都会重新被创建,原因如下:
只有被relaunch的activity在destroy时才会在ActivityThread代码中被调用retainNonConfig去通知Activity返回需要保存实例,其他的destroy不会。
所谓relaunch是指 比如我们手动调用了activity的recreate方法,或者更改了系统语言 屏幕方向等造成的activity重新创建。而系统资源不足回收造成的activity重新创建
是不属于relaunch这一行为的
- 海报