回顾
在Fragment在生命周期中是如何走到onCreateView的(一)中,主要从代码上走了一下,如何从调用replace.commit开始,走到fragment生命周期的各关键方法的。
其中比较重要的方面有:
1. FragmentManager负责控制fragment生命周期的流转,重要方法是moveToState
2. BackStackRecord负责处理和分发对fragment的一系列操作,最终会走到FragmentManager的moveToState
一般来说,我们调用fragment,用到的方法都是replace,add,remove,show,hide,attach,detach这一些,这些都是由BackStackRecord来实现的:
1. BackStackRecord首先会将这些操作封装成一个个Op。Op里包含对应的操作方式,上一个Op,下一个Op,进出动画等。
static final class Op {
Op next;
Op prev;
int cmd;
Fragment fragment;
int enterAnim;
int exitAnim;
int popEnterAnim;
int popExitAnim;
ArrayList<Fragment> removed;
}
2. BackStackRecord将操作封装成Op之后,并不会立即执行,而是将Op放到一个双向链表中。从Op的结构也可以看出,Op是链表中的一个结点。从获取BackStackRecord的方法beginTransaction也可以看出,这里就是一个事务的概念。
3. BackStackRecord是一个Runnable,在commit之后,FragmentManager会执行Runnable的run,这时就会把链表中的Op循环一遍。
4. 对每个Op来说,根据操作类型,会分别执行到FragmentManager的addFragment,removeFragment,hideFragment,showFragment,detachFragment,attachFragment等方法
5. 之后就会进入到moveToState
以上就是对上一篇的回顾。
本文来看一下在moveToState是如何走到onCreateView的
Fragment的state
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
static final int STOPPED = 3; // Fully created, not started.
static final int STARTED = 4; // Created and started, not resumed.
static final int RESUMED = 5; // Created started and resumed.
Fragemnt的状态包括这六种,从0到5,从小到大,从initial到resume,可以看作一个状态上升的过程。相反,从5到0,则可以看到状态下降。
而在状态之间切换的时候,就会调用我们熟知的那些生命周期方法。
初始状态
在我们调用replace或者add后,都会在BackStackRecord的run中,执行
mManager.moveToState(mManager.mCurState, transition, transitionStyle, true);
最终会调用到FragmentManager的moveToState
void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) {
具体代码就不再贴一遍了。
newState是mManager.mCurState,即是FragmentManager的state,具体是什么我还没仔细研究,应该是跟Activity的状态一致吧,如果我们实在Activity的onCreate中调用的,暂且认为是STOPPED(created, not started)
开始会有一些状态的判断,先略去。
然后会走到第一个判断。
if (f.mState < newState) {
// 这里处理状态上升
} else if (f.mState > newState) {
// 这里处理状态下降
}
f的状态,初始是INITIALIZING,肯定会小于STOPPED,进入状态上升的处理逻辑
接下来是switch判断
switch (f.mState) {
case Fragment.INITIALIZING:
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
}
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
}
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
}
}
可以看到,会根据fragment的state来进入相应的case。
而且,case是没有break的,也就是会一直按顺序执行到newState对应的方法。
Fragment.INITIALIZING
注意到几个语句
f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
f.mCalled = false;
f.onAttach(mHost.getContext());
...
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
} else {
f.mParentFragment.onAttachFragment(f);
}
...
if (f.mFromLayout) {
// For fragments that are part of the content view
// layout, we need to instantiate the view immediately
// and the inflater will take care of adding it.
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
}
给fragment赋了Host,host中就包括Activity和Context
赋了父Fragment
赋了相应的FragmentManager
执行fragment的onAttach
然后执行相应的Activity或者父Fragment的onAttachFragment
如果fragment直接是view layout的一部分,则马上执行createView。这时就会走到onCreateView
View performCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mChildFragmentManager != null) {
mChildFragmentManager.noteStateNotSaved();
}
return onCreateView(inflater, container, savedInstanceState);
}
这是其中一个onCreateView,但我们一般使用中,更多是另外一个,在后面。
Fragment.CREATED
if (newState > Fragment.CREATED) {
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
...
container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
...
}
f.mContainer = container;
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
...
if (container != null) {
...
container.addView(f.mView);
}
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);
} else {
f.mInnerView = null;
}
f.performActivityCreated(f.mSavedFragmentState);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
首先根据containerId找到容器ViewGroup,并赋给f.mContainer
然后就是performCreateView,也就是另外一个onCreateView,这是当fragment不是view layout的一部分的情况。赋给f.mView
接着把f.mView添加到container里面
然后走fragment的onViewCreated
之后会调用fragment的performActivityCreated,里面就会走到onActivityCreated
至此,我们就找到了onCreateView
其余
剩下的几个case也会有相应的逻辑。
状态下降的过程也类似,只不过执行了相对来说相反的逻辑
最后
if (f.mState != newState) {
...
f.mState = newState;
}
会把fragment的状态更新
小结
这里可以看到moveToState是fragment生命周期流转的关键方法。本文主要从调用add或者replace往下顺的,还有其他情况,比如当Activity生命周期发生变化时,也会走moveToState,进而让fragment走对应的生命周期方法。
问题
这里有个问题,就是FragmentManager的state变化,我并没有细究,应该是跟Activity的是一致的,本文是基于此进行的分析,后面有机会可以研究一下。