androidx.appcompat:appcompat:1.0.2
androidx.lifecycle:lifecycle-extensions:2.2.0-alpha02
对于Fragment的生命周期,先来了解一下Fragment的state,有5种状态,默认状态为INITIALIZING
//Fragment.java
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // Fully created, not started.
static final int STARTED = 3; // Created and started, not resumed.
static final int RESUMED = 4; // Created started and resumed.
int mState = INITIALIZING;
众所周知,Fragment的生命周期其实跟Activity的生命周期是有关的,系统最终会调用到Activity的onCreate等生命周期方法,其中FragmentActivity重写了生命周期方法,在内部根据生命周期的不同,给Fragment分发不同的state状态。其实在Activity中,也有对Fragment进行state的分发,其中Fragment的状态有6种,根据猜测,这应该是在直接继承Activity的情形下出现的,现在还是关注继承AppCompatActivity情形下,Fragment的一种生命周期的表现。

newState,Fragment当前的状态称之为curState,先上个图

从图中可以大致得出,Activity中每一次newState的分发都会进入该判断流程中,根据发出的newState和Fragment当前的curState做判断,根据判断的结果选择状态是从上往下迁移还是从下往上迁移,每一种Fragment状态都会执行相对应的生命周期方法,在每个状态的执行最后会将curState设置为下一个状态,继续执行判断,直至一个流程结束或比较判断结果为false。主要的判断流程源码在FragmentManagerImpl内的moveToState方法。
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
...
//若当前fragment的状态小于等于新的状态时,比如fragment默认INITIALIZING,分发来的状态为CREATED
if (f.mState <= newState) {
...
switch (f.mState) {
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
...
//最终调用到onAttach
f.performAttach();
...
//如果fragment还未create
if (!f.mIsCreated) {
dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
//调用到fragment的onCreate,并且fragment的state设置为CREATED,mIsCreated设置为true
f.performCreate(f.mSavedFragmentState);
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = Fragment.CREATED;
}
}
//由于上面的case没有执行break,继续判断,上面的case中已经将fragment的state设置为CREATED
case Fragment.CREATED:
//标记点1
if (newState > Fragment.INITIALIZING) {
ensureInflatedFragmentView(f);
}
if (newState > Fragment.CREATED) {
if (!f.mFromLayout) {
...
//走到fragment的onCreateView,内部还会创建一个LifecycleRegistry
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
...
f.onViewCreated(f.mView, f.mSavedFragmentState);
...
}
...
}
//调用到fragment的onActivityCreated,fragment的state设置为ACTIVITY_CREATED
f.performActivityCreated(f.mSavedFragmentState);
...
}
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
//调用到fragment的onStart,fragment的state设置为STARTED
f.performStart();
dispatchOnFragmentStarted(f, false);
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
//调用到fragment的onResume,fragment的state设置为RESUMED
f.performResume();
dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
} else if (f.mState > newState) {
//若新的状态小于fragment当前的状态时
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
//调用到fragment的onPause,fragment的state设置为STARTED
f.performPause();
dispatchOnFragmentPaused(f, false);
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
//调用到fragment的onStop,fragment的state设置为ACTIVITY_CREATED
f.performStop();
dispatchOnFragmentStopped(f, false);
}
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
...
//调用到fragment的onDestroyView,fragment的state设置为CREATED
f.performDestroyView();
dispatchOnFragmentViewDestroyed(f, false);
...
f.mContainer = null;
f.mView = null;
f.mViewLifecycleOwner = null;
f.mViewLifecycleOwnerLiveData.setValue(null);
f.mInnerView = null;
f.mInLayout = false;
}
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
...
if (f.getAnimatingAway() != null || f.getAnimator() != null) {
f.setStateAfterAnimating(newState);
newState = Fragment.CREATED;
} else {
...
if (beingRemoved || mNonConfig.shouldDestroy(f)) {
...
//调用到fragment的onDestroy,fragment的state设置为INITIALIZING
f.performDestroy();
dispatchOnFragmentDestroyed(f, false);
} else {
f.mState = Fragment.INITIALIZING;
}
//调用到fragment的onDetach
f.performDetach();
dispatchOnFragmentDetached(f, false);
...
}
}
}
}
if (f.mState != newState) {
f.mState = newState;
}
}
在moveToState方法内,还有一个最大生命周期的判断
if (f.mMaxState == Lifecycle.State.CREATED) {
newState = Math.min(newState, Fragment.CREATED);
} else {
newState = Math.min(newState, f.mMaxState.ordinal());
}
表示如果Fragment设置了MaxState(Fragment可以实现的最大生命周期状态,默认为Lifecycle.State.RESUME),若设置的最大状态为Lifecycle.State.CREATED,那么只要Activity分发的newState大于CREATED,就都会被设置为CREATED,此时打开一个Activity,按照上面的流程图可以知道该Activity内部的Fragment的生命周期只会走到onCreate,关闭Activity的时候,也只有在onDestory的时候分发的INITIALIZING小于当前Fragment所在的CREATED,根据当前Fragment的状态,从上图可知,会进入onDestory和onDetach生命周期。以此类推其他最大生命周期的状态下的Fragment生命周期流程。最大生命周期可以通过FragmentTransaction来设置。
supportFragmentManager.beginTransaction().apply {
add(R.id.fragment_content, fragment)
setMaxLifecycle(fragment, Lifecycle.State.CREATED)
commit()
}
并不是一开始分发newState就会进入moveToState方法的,那么它都会在什么时候被真正的调用呢,在addFragment之后。Fragment添加方式包括使用FragmentTransaction来添加以及直接在xml使用fragment标签。当使用FragmentTransaction来添加的时候,会调用commit方法,最终实现在BackStackRecord中的commitInternal内,调用到FragmentManagerImpl,通过Handler发送一个mExecCommit信息
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
execPendingActions方法最终会执行到FragmentManagerImpl的addFragment方法,实际上该方法在FragmentActivity中的onStart和onResume去分发newState之前都会调用一次,即表示不论在onCreate、onStart、onResume哪个生命周期内调用commit方法,都能及时的将Fragment的INITIALIZING迁移至newState。
protected void onStart() {
super.onStart();
mStopped = false;
if (!mCreated) {
mCreated = true;
mFragments.dispatchActivityCreated();
}
mFragments.noteStateNotSaved();
//here
mFragments.execPendingActions();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
mFragments.dispatchStart();
}
从上面分析可以得出,Fragment根据在Activity的不同生命周期内去commit,会在相应的生命周期之后再去执行Fragment的moveToState,按照流程图,从onAttach开始一直到该Activity生命周期分发的newState能到达的最大状态,比如在onStart内添加Fragment(在其他生命周期内一定要注意不能重复commit)

如果采用的是直接在xml布局中使用fragment标签来添加,先看一下其生命周期流程

在LayoutInflater中,去xml中解析布局信息去创建View的时候,对于存在fragment的情况下,最终会调用到FragmentLayoutInflaterFactory的onCreateView方法,在该方法内有这么一段代码
if (fragment == null) {
fragment = mFragmentManager.getFragmentFactory().instantiate(
context.getClassLoader(), fname);
fragment.mFromLayout = true;
fragment.mFragmentId = id != 0 ? id : containerId;
fragment.mContainerId = containerId;
fragment.mTag = tag;
fragment.mInLayout = true;
fragment.mFragmentManager = mFragmentManager;
fragment.mHost = mFragmentManager.mHost;
fragment.onInflate(mFragmentManager.mHost.getContext(), attrs,
fragment.mSavedFragmentState);
//第二个参数为true,在addFragment的最后会调用moveToState方法
//将FragmenManager记录的state作为newState
mFragmentManager.addFragment(fragment, true);
}
...
//如果记录的state比CREATED小,那么就将Fragment迁移到CREATED状态,反之则将Fragment迁移到记录的state
if (mFragmentManager.mCurState < Fragment.CREATED && fragment.mFromLayout) {
mFragmentManager.moveToState(fragment, Fragment.CREATED, 0, false);
} else {
mFragmentManager.moveToState(fragment);
}
按照当前的情况,现在顶多只把INITIALIZING迁移到了CREATED,那么按照上面的流程图,这时候Fragment的生命周期应该只到onCreate才对,但是上面的打印结果却是到onViewCreated,原因就是在上面moveToState代码中的标记点1,在case Fragment.CREATED中
if (newState > Fragment.INITIALIZING) {
ensureInflatedFragmentView(f);
}
此时判断进入ensureInflatedFragmentView方法,满足了方法内的条件判断,所以继续调用了onCreateView和onViewCreated
void ensureInflatedFragmentView(Fragment f) {
if (f.mFromLayout && !f.mPerformedCreateView) {
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
f.mView.setSaveFromParentEnabled(false);
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
} else {
f.mInnerView = null;
}
}
}
ok,完结撒花