文章目录
概述
Fragment的生命周期依托FragmentActivity管理调度,在FragmentActivity的各个生命周期方法回调中,会将对应生命状态派发给依附于FragmentActivity的所有Fragment。
源码探究
文中源码基于’androidx.fragment:fragment:1.1.0’
Fragment的生命周期派发
上图为FragmentActivity和Fragment的生命周期对照,随着FragmentActivity的生命周期变化,也会调整Fragment的生命周期状态。
FragmentActivity首先会设置FragmentManagerImpl中的生命状态,再通过FragmentManagerImpl来更新其中的Fragment的状态。
状态常量值
在Fragment类中定义了5个状态常量值,用于标记当前状态:
- INITIALIZING(0):初始状态、默认状态,和图2中onDestroy状态
- CREATED(1):对应图2中Created、onDestroyView状态
- ACTIVITY_CREATED(2):对应图2中onActivityCreated至Started、Stopped状态
- STARTED(3):对应图2中Started、Paused状态
- RESUMED(4):对应图2中Resumed状态
FragmentManagerImpl利用mCurState成员变量来标记当前状态,Fragment利用mState成员变量来标记当前状态。
更新FragmentManagerImpl的生命周期状态
这里以FragmentActivity的生命周期回调开始,先看派发给FragmentManagerImpl各个状态的时机。
onCreate
[FragmentActivity.java]
protected void onCreate(@Nullable Bundle savedInstanceState) {
// 进行上下文绑定,FragmentManagerImpl会持有HostCallbacks引用
mFragments.attachHost(null /*parent*/);
// 省略savedInstanceState部分 ···
// 省略mPendingFragmentActivityResults部分 ···
super.onCreate(savedInstanceState);
// 省略LifecycleRegistry部分 ···
// 通过FragmentController来调用FragmentManagerImpl
mFragments.dispatchCreate();
}
FragmentActivity中调用FragmentManagerImpl的相关方法都是通过FragmentController来间接调用。
继续看dispatchCreate方法:
[FragmentController.java]
public void dispatchCreate() {
// 通过FragmentHostCallback来调用FragmentManagerImpl
mHost.mFragmentManager.dispatchCreate();
}
这里最终调用了FragmentManagerImpl的dispatchCreate方法:
[FragmentManagerImpl.java]
public void dispatchCreate() {
// mStateSaved用于标记是否保存Fragment State(通过saveAllState方法保存)
mStateSaved = false;
// mStopped用于标记当前是否Stopped
mStopped = false;
// 传入状态值CREATED
dispatchStateChange(Fragment.CREATED);
}
该方法中调用dispatchStateChange方法并传入CREATED来更新状态。
[FragmentManagerImpl.java]
private void dispatchStateChange(int nextState) {
try {
mExecutingActions = true;
// 变更当前状态为传入的目标状态
moveToState(nextState, false);
} finally {
mExecutingActions = false;
}
// 处理待执行任务队列
execPendingActions();
}
真正更新状态是在moveToState方法中:
[FragmentManagerImpl.java]
void moveToState(int newState, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
// 检查状态是否相等,always此时传入的为false
if (!always && newState == mCurState) {
return;
}
// 更新状态
mCurState = newState;
// 省略触发Fragment更新状态部分
// ···
}
在该方法中将传入的指定的状态赋值给了mCurState成员,从而达到FragmentManagerImpl的状态更新。
onStart
[FragmentActivity.java]
protected void onStart() {
super.onStart();
mStopped = false;
// mCreated默认为false
if (!mCreated) {
mCreated = true;
// 派发ACTIVITY_CREATED状态
mFragments.dispatchActivityCreated();
}
mFragments.noteStateNotSaved();
mFragments.execPendingActions();
// NOTE: HC onStart goes here.
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
// 派发STARTED状态
mFragments.dispatchStart();
}
在onStart方法中,判断若是首次调用,则会调用dispatchActivityCreated方法。最后调用dispatchStart方法。这两个方法同dispatchCreate方法一样,通过FragmentController->FragmentHostCallback->FragmentManagerImpl调用对应方法。
[FragmentManagerImpl.java]
public void dispatchActivityCreated() {
mStateSaved = false;
mStopped = false;
// 派发ACTIVITY_CREATED状态
dispatchStateChange(Fragment.ACTIVITY_CREATED);
}
public void dispatchStart() {
mStateSaved = false;
mStopped = false;
// 派发STARTED状态
dispatchStateChange(Fragment.STARTED);
}
前后更新状态为ACTIVITY_CREATED和STARTED。
onPostResume
在Activity的performResume方法中会调用onPostResume方法:
[Activity.java]
final void performResume(boolean followedByPause, String reason) {
// ···
// 将会触发Activity的onResume回调
mInstrumentation.callActivityOnResume(this);
// ···
onPostResume();
// ···
}
而FragmentActivity重写了onPostResume方法:
[FragmentActivity.java]
protected void onPostResume() {
super.onPostResume();
onResumeFragments();
}
protected void onResumeFragments() {
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
// 派发RESUMED状态
mFragments.dispatchResume();
}
dispatchResume方法最终会调用FragmentManagerImpl的dispatchResume方法,将状态更新为RESUMED。
onPause
[FragmentActivity.java]
protected void onPause() {
super.onPause();
mResumed = false;
// 派发STARTED状态
mFragments.dispatchPause();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
[FragmentManagerImpl.java]
pub