7、moveToState
上一盘说Fragment的生命周期说到了moveToState这个方法,这篇我们继续:
首先看moveToState这个方法的定义:
void moveToState(Fragment f, int newState, int transit, int transitionStyle,boolean keepActive)
static final int INVALID_STATE = -1; // Invalid state used as a null value.
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.
在moveToState方法一开始,会对传入的newState进行校准,具体方式如下:
//如果传入的newState大于Fragment.CREATED,那么在两种情况下将他强行设置为Fragment.CREATED
//1、这个fragment已经被移除了,即调用removeFragment方法
//2、这个fragment已经没有附着在当前activity上了,即调用了detachFragment方法
if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
newState = Fragment.CREATED;
}
//如果fragment已经被remove掉了,那么如果传入的newState大于原始的mState时,是不能增加mState的值的
if (f.mRemoving && newState > f.mState) {
// While removing a fragment, we can't change it to a higher state.
newState = f.mState;
}
//如果fragment要求延时start,并且fragment的原状态小于STARTED,而传入的状态大于STOPPED(最少为STARTED),那么强行将状态置为STOPPED
if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
newState = Fragment.STOPPED;
}
校准完毕之后,就开始同步状态,同步状态有两种情况,一种是传入的newState大于原有的mState,这时状态会上升,另外一种是小于,这时状态会下降。
在状态上升中,是通过switch-case进行不同分支跳转的,但是在这个case的最后并没有使用break语句跳出分支,这时因为在执行完前一个状态的逻辑后,还需要继续往后执行,所有它其中的case分支都是按照INITIALIZING、CREATED、ACTIVITY_CREATED、STOPPED、STARTED、RESUMED顺序排布的,因为代码较长,所以这里都以注释的形式进行说明。
INITIALIZING:
//首先会判断mSavedFragmentState是否为null,这个是用来保存状态恢复而使用的,和Activity非正常销毁时保存状态类似
if (f.mSavedFragmentState != null) {
......
}
//配置fragment的参数
......
//验证一些信息
f.mCalled = false;
f.onAttach(mActivity);
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onAttach()");
}
if (f.mParentFragment == null) {
mActivity.onAttachFragment(f);
}
//执行fragment的生命周期
if (!f.mRetaining) {
//在这里会调用fragment的performCreate方法,在performCreate方法中会调用生命周期的onCreate方法
f.performCreate(f.mSavedFragmentState);
}
f.mRetaining = false;
//如果这个fragment是layout中的,那么还执行另外的一些生命周期
if (f.mFromLayout) {
//performCreateView方法中会调用onCreateView方法
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
//如果从onCreateView获得的View不为null,那么还会调用onViewCreated方法
if (f.mView != null) {
f.mView.setSaveFromParentEnabled(false);
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);
}
}
CREATED:
//因为上面的一个case没有break,所以从第二个case开始,都会先判断newState,才能决定是否继续执行当前state的逻辑
if (newState > Fragment.CREATED) {
if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
//如果fragment不是layout中的,那么就会执行fragment的生命周期(和INITIALIZING中类似)
//不过这里还添加了一个新的逻辑,那就是拿到fragment需要填充的view的id,在fragment的view构建完毕之后,
//通过container.addView(f.mView),将fragment添加到需要填充的view中,
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
container = (ViewGroup)mContainer.onFindViewById(f.mContainerId);
if (container == null && !f.mRestored) {
throwException(new IllegalArgumentException(
"No view found for id 0x"
+ Integer.toHexString(f.mContainerId) + " ("
+ f.getResources().getResourceName(f.mContainerId)
+ ") for fragment " + f));
}
}
f.mContainer = container;
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mView.setSaveFromParentEnabled(false);
if (container != null) {
Animator anim = loadAnimator(f, transit, true,
transitionStyle);
if (anim != null) {
anim.setTarget(f.mView);
setHWLayerAnimListenerIfAlpha(f.mView, anim);
anim.start();
}
container.addView(f.mView);
}
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);
}
}
//执行完生命周期之后,调用ChildFragment中的performActivityCreated方法,这样最终会调用到ChildFragment中的moveToState方法
f.performActivityCreated(f.mSavedFragmentState);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
ACTIVITY_CREATED:
STOPPED:
if (newState > Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
//如果newState大于STOPPED(至少是STARTED),那么调用fragment的生命周期onStart方法
f.performStart();
}
STARTED:
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
f.mResumed = true;
//调用fragment的生命周期onResume
f.performResume();
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
到这里,提升状态的逻辑基本就说完了,理解完提升状态的逻辑,那么降低状态的逻辑也就大同小异了,这里就放一起说了:
降低状态:
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
//如果小于RESUMED,那么调用生命周期onPause
f.performPause();
f.mResumed = false;
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
//如果小于STARTED,那么调用生命周期onStop
f.performStop();
}
case Fragment.STOPPED:
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
//如果mView不为null,清除之前保存的一些状态
if (f.mView != null) {
if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
saveFragmentViewState(f);
}
}
//调用onDestroyView生命周期方法
f.performDestroyView();
//如果有退出动画,那么播放退出动画
if (f.mView != null && f.mContainer != null) {
Animator anim = null;
if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
anim = loadAnimator(f, transit, false,
transitionStyle);
}
if (anim != null) {
final ViewGroup container = f.mContainer;
final View view = f.mView;
final Fragment fragment = f;
container.startViewTransition(view);
f.mAnimatingAway = anim;
f.mStateAfterAnimating = newState;
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator anim) {
container.endViewTransition(view);
if (fragment.mAnimatingAway != null) {
fragment.mAnimatingAway = null;
moveToState(fragment, fragment.mStateAfterAnimating,
0, 0, false);
}
}
});
anim.setTarget(f.mView);
setHWLayerAnimListenerIfAlpha(f.mView, anim);
anim.start();
}
//将fragment的view从界面移除
f.mContainer.removeView(f.mView);
}
f.mContainer = null;
f.mView = null;
}
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
if (mDestroyed) {
//如果fragment的Activity销毁,那么停止fragment的动画,并将mAnimatingAway设置为null
if (f.mAnimatingAway != null) {
Animator anim = f.mAnimatingAway;
f.mAnimatingAway = null;
anim.cancel();
}
}
if (f.mAnimatingAway != null) {
//如果mAnimatingAway没有设置为null,那么状态不变
f.mStateAfterAnimating = newState;
newState = Fragment.CREATED;
} else {
//如果mAnimatingAway状态为null
if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
if (!f.mRetaining) {
//调用fragment的生命周期onDestroy
f.performDestroy();
}
f.mCalled = false;
//调用fragment的生命周期onDetach
f.onDetach();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onDetach()");
}
if (!keepActive) {
if (!f.mRetaining) {
//回收fragment的index
makeInactive(f);
} else {
f.mHost = null;
f.mParentFragment = null;
f.mFragmentManager = null;
f.mChildFragmentManager = null;
}
}
}
}
总结
①到这里,Fragment的源码也算是基本完结了,相比于Activity,Fragment更像一个java类,它没有Activity那样实现很多的视图接口,也没有实现任何的键盘监听,从这里我们就可以确定fragment里的键盘事件应该是通过Activity传入的。
②在我们使用Fragment的时候,通过getFragmentManager方法拿到的其实是FragmentManagerImpl,他是FragmentManagerI的子类。而Fragment的生命周期,也是通过它进行控制的。
③在我们通过beginTransaction,add方法添加Fragment的时候,只是把Fragment和操作类型保存到一个BackStackRecord的Op对象中去了,虽然Fragment对象是通过我们new Fragment创建出来的,但是此时的Fragment并没有执行它生命周期的onCreate方法,这点和Activity是不同的,Activity是会在系统创建它之后,立刻执行它出onCreate方法。
④对Fragment状态的的变更,是在我们调用完commit方法后才开始的,他会通过mHandler.post(mExecCommit),最后调用到execPendingActions方法中。
⑤在execPendingActions方法中,会拿到之前在BackStackRecord对象,而BackStackRecord是实现了Runnable接口是,所以会执行BackStackRecord中的run方法。
⑥在BackStackRecord 的run中,会针对不同的操作类型,比如add,remove调用FragmentManagerImpl中不同的方法,例如addFragment,removeFragment,在这些方法中,首先会更改fragment对象中对应的配置参数,然后会将fragment传入调用moveToState方法。
⑦在FragmentManagerImpl的moveToState方法中,会调用Fragment的生命周期方法。
上述,就是Fragment源码中,对于Fragment生命周期的调用了,当然还是那句话,Android的源码远比我看的复杂,而我当前也只是通过一个简单的例子来看Fragment的生命周期,自然不可能面面俱到,至于其中的细节部分,还是需要以后慢慢研究咯。