- FragmentActivity的onSaveInstanceState(Bundle outState)会调用:
mFragments.saveAllState(),其返回一个Parcelable对象,并会将此对象放在onSaveInstanceState提供的
Bundle中,
mFragments其实是一个FragmentManagerImpl<位于support v4的FragmentManager.java中> - FragmentManagerImpl saveAllState()的流程:
(1)execPendingActions() 将没有执行的Transaction执行,确保state是update-to-date的.
(2)对于Android3.0 HC以上 >= 11, 会专门将mStateSaved设为true: 注释是这么说的
对于HC及以上的版本, 会在pausing以后再进行save state, 而在之前的版本,则是在pausing之前进行的,
这就带来一个问题,在pausing之后 stoppping之前,可能会有很多操作会改变fragment的state, 对于这些旧设备,
是不能肯定的说,state是确实被正确的save了,但是呢,到了这份上也没办法,所以对于旧设备就由他去吧,但是新设备会通过mStateSaved做check,后面的一个异常就是这个check。
(3)内部维护的一个Fragment列表,mActive. 如果发现mActive都没有,那么显然不需要save 什么 state,直接return.
(4)创建一个FragmentState数组, 遍历mActive,如果Fragment确实存在且mIndex>=0有效,那么目前的Manager中就确实是
有Fragment的,以该fragment作为参数构造一个FragmentState<已经得到了state>,并赋给相应的FragmentState数组,
然后再做个判断,如果Fragment的state > ragment.INITIALIZIN并且FragmentState还没有 mSavedFragmentState,
那么就为次FragmentState创建一个saveFragmentBasicState(Fragment),否则直接取Fragment的mSavedFragmentState即可,
可以看出来,每个Fragment在创建出来的时候是没有FragmentState<一个bundle>的,在save的时候,如果没有,就会为其创建一个,并
自己维护一个引用,以后再save state的时候,就可以直接save了. 构造出的FragmentState数组会保存到一个FragmentManagerState
对象的mActive引用上。
(5) 下一步是将自己内部的一个Int[]的mAdded保存的fragment的index重新保存到一个added里,并进一步存为到FragmentManagerState的
mActive数组。
(6) 一个BackStackState列表也被构造并根据FragmentManager的mBackStack进行设置,然后保存到一个FragmentManagerState中。
(7) 最后返回之前构造的那个FragmentManagerState对象,可以看出,Fragment保存state的过程其实也听简单的,
先把每个Fragment的state进行保存,然后保存FragmentManager本身的一些信息,最后把这些信息都保存到一个FragmentManagerState
对象中,供以后的restore.
restoreAllState()函数基本就是上面的逆过程,这也就是Fragment 自己的 onSave/RestoreInstanceState(bundle outState)的
外部调用过程: saveAllState() -> saveFragmentBasicState(fragment) -> fragment.performSaveInstanceState(mStateBundle)
-> onSaveInstanceState(Bundle outState).
(8) checkStateLoss()在mStateSaved的情况下,会throw一个IllegalStateException:
“Can not perform this action after onSaveInstanceState”, throw的原因结合(2)也可以得出: 在
mStateSaved为true的情况下,Fragment以及FragmentManager的信息都已经被save 到bundle了,
这时候不能再有其他可能改变Fragment state的操作,否则 最后restore出来的state信息会不一致,因此
这里会抛一个异常告知这种操作的非法.
Android Fragment State Saving. 以及 Can not perform this action after onSaveInstanceState 异常.
最新推荐文章于 2017-08-19 15:28:31 发布