前言
本文为个人学习Fragment源码时所总结形成的文章。本文主要梳理Fragment生命周期的调用流程
Fragment的声明流程。
如大家所知道的,Fragment被称为'碎片',我理解的碎片就是可以将fragment嵌入到相关的activity页面中,展示相关的布局,并能够监听activity的相关声明周期,并执行相关的逻辑。
class MainActivity : AppCompatActivity() {
companion object {
private const val TAG = "MainActivity"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.e(TAG, "onCreate: ")
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<fragment
android:id="@+id/my"
android:name="com.zxl.fragmentlifecycledemo.MyFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.zxl.fragmentlifecycledemo
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
class MyFragment : Fragment() {
companion object {
private const val TAG = "MyFragment"
}
override fun onAttach(context: Context) {
super.onAttach(context)
Log.e(TAG, "onAttach: ")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.e(TAG, "onCreate: ")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Log.e(TAG, "onActivityCreated: ")
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val inflate = inflater.inflate(R.layout.fragment_main, container, false)
Log.e(TAG, "onCreateView: ")
return inflate
}
}
运行后的结果如下:
2021-10-11 15:39:31.871 14480-14480/com.zxl.fragmentlifecycledemo E/MyFragment: onAttach:
2021-10-11 15:39:31.871 14480-14480/com.zxl.fragmentlifecycledemo E/MyFragment: onCreate:
2021-10-11 15:39:31.874 14480-14480/com.zxl.fragmentlifecycledemo E/MyFragment: onCreateView:
2021-10-11 15:39:31.874 14480-14480/com.zxl.fragmentlifecycledemo E/MainActivity: onCreate:
2021-10-11 15:39:31.878 14480-14480/com.zxl.fragmentlifecycledemo E/MyFragment: onActivityCreated:
从代码运行的结果来说,在Activity执行完onCreate之前Fragment已经执行了onAttach,onCreate,onCreateViewdd这三个方法,在Activity的onCreate执行完之前,Fragment又调用了onActivityCreaged的方法。其实大家都知道,Activity会主动调用Fragemnt的相关周期(可以类比于ViewGroup的onMeasure,先测量完所有的子View最后才测量自己)。那我们就从Activity的onCreate方法作为入口看一下吧。
AppCompatActivity的onCreate方法
protected void onCreate(@Nullable Bundle savedInstanceState) {
final AppCompatDelegate delegate = getDelegate();
delegate.installViewFactory();
delegate.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
AppCompatActivity会调用FragmentActivity的onCreate方法
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
super.onCreate(savedInstanceState);
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
//这里调用了mFragments的dispatchCreate方法
mFragments.dispatchCreate();
...
}
在FragmentActivity的onCreate方法中调用了dispatchCreate方法,首先注意调用方mFragments,这个mFragments是什么呢,其实就是FragmentController,我喜欢叫他'''大管家',他其实像一个静态代理一样,所有与Fragment的操作都通过mHost调用相关方法实现,而mHost调用mFragmentManager实现相关的操作
public class FragmentController {
private final FragmentHostCallback<?> mHost;
/**
* Returns a {@link FragmentController}.
*/
@NonNull
public static FragmentController createController(@NonNull FragmentHostCallback<?> callbacks) {
return new FragmentController(checkNotNull(callbacks, "callbacks == null"));
}
private FragmentController(FragmentHostCallback<?> callbacks) {
mHost = callbacks;
}
/**
* Returns a {@link FragmentManager} for this controller.
*/
@NonNull
public FragmentManager getSupportFragmentManager() {
return mHost.mFragmentManager;
}
/**
* Returns a {@link LoaderManager}.
*
* @deprecated Loaders are managed separately from FragmentController and this now throws an
* {@link UnsupportedOperationException}. Use {@link LoaderManager#getInstance} to obtain a
* LoaderManager.
* @see LoaderManager#getInstance
*/
@Deprecated
@SuppressLint("UnknownNullness")
public LoaderManager getSupportLoaderManager() {
throw new UnsupportedOperationException("Loaders are managed separately from "
+ "FragmentController, use LoaderManager.getInstance() to obtain a LoaderManager.");
}
/**
* Returns a fragment with the given identifier.
*/
@Nullable
public Fragment findFragmentByWho(@NonNull String who) {
return mHost.mFragmentManager.findFragmentByWho(who);
}
.....
}
public abstract class FragmentHostCallback<E> extends FragmentContainer {
@Nullable private final Activity mActivity;
@NonNull private final Context mContext;
@NonNull private final Handler mHandler;
private final int mWindowAnimations;
//FragmentHostCallBack持有FragmentManagerImpl 的实例
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
现在看一下mFragments的dispatchCreate方法
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
该方法最终调用了FragmentHostCallBack持有的FragmentManagerImpl的dispatchCreate。FragmentManagerImpl的dispatchCreate方法如下
public void dispatchCreate() {
mStateSaved = false;
mStopped = false;
//调用dispatchStateChange
dispatchStateChange(Fragment.CREATED);
}
这里需要注意的是Fragment.CREATED这个状态位,在Fragment总一共有五个状态(这里只说明AndroidX的版本)
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
ViewModelStoreOwner, SavedStateRegistryOwner {
static final Object USE_DEFAULT_TRANSITION = new Object();
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.
不知道这里大家会不会奇怪为什么没有paused,Stoped之类的状态符,这是因为INITIALIZING ->RESUMED 这种算升序的话,RESUMED ->INITIALIZING 则可以理解为降序。没有必须再设置Paused之类。那么dispatchStateChange又干了什么呢?
private void dispatchStateChange(int nextState) {
try {
mExecutingActions = true;
//调用了moveToState方法
moveToState(nextState, false);
} finally {
mExecutingActions = false;
}
execPendingActions();
}
这个方法就整个Fragment操作的一个核心方法,里面处理了各种fragment的声明周期的回调。
void moveToState(int newState, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
if (!always && newState == mCurState) {
return;
}
mCurState = newState;
// Must add them in the proper order. mActive fragments may be out of order
//将mAdded集合的fragment回调相关的声明周期
final int numAdded = mAdded.size();
for (int i = 0; i < numAdded; i++) {
Fragment f = mAdded.get(i);
moveFragmentToExpectedState(f);
}
// Now iterate through all active fragments. These will include those that are removed
// and detached.
for (Fragment f : mActive.values()) {
if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
moveFragmentToExpectedState(f);
}
}
startPendingDeferredFragments();
if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
mHost.onSupportInvalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
}
在该方法中循环遍历mAdded的Fragments,并moveFragmentToExpectedState,通过该方法回调各个Fragment的声明周期方法。
void moveFragmentToExpectedState(Fragment f) {
if (f == null) {
return;
}
if (!mActive.containsKey(f.mWho)) {
if (DEBUG) {
Log.v(TAG, "Ignoring moving " + f + " to state " + mCurState
+ "since it is not added to " + this);
}
return;
}
int nextState = mCurState;
if (f.mRemoving) {
if (f.isInBackStack()) {
nextState = Math.min(nextState, Fragment.CREATED);
} else {
nextState = Math.min(nextState, Fragment.INITIALIZING);
}
}
//调用moveToState
moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
....
}
现在看一下moveToState这个方法
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
.....
//当前Frgamnet状态小于等于指定的状态状态,执行下面的方法
if (f.mState <= newState) {
....
} else if (f.mState > newState) {
//当前Frgamnet状态大于指定的状态状态,执行下面的方法
......
}
....
现在看一下Fragment的mState小于等于newState的情况
switch (f.mState) {
//当前Fragment状态为初始化状态
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
.....
f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mHost.mFragmentManager;
//调用Fragment的f.performAttach方法,该方法最终调用到Fragment的onAttach方法
f.performAttach();
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
} else {
f.mParentFragment.onAttachFragment(f);
}
dispatchOnFragmentAttached(f, mHost.getContext(), false);
//无论f.mIsCreate取值为何,都会将Fragment的状态置为 Fragment.CREATED
if (!f.mIsCreated) {
dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
//调用fragment的performCreate,最终会调用到Fragment的onCreate方法,该放回会将mState置为Fragment.CREATED
f.performCreate(f.mSavedFragmentState);
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = Fragment.CREATED;
}
}
// fall through
//这里没有break,所以会走到下面一个case
case Fragment.CREATED:
// We want to unconditionally run this anytime we do a moveToState that
// moves the Fragment above INITIALIZING, including cases such as when
// we move from CREATED => CREATED as part of the case fall through above.
if (newState > Fragment.INITIALIZING) {
ensureInflatedFragmentView(f);
}
if (newState > Fragment.CREATED) {
if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
if (f.mContainerId == View.NO_ID) {
throwException(new IllegalArgumentException(
"Cannot create fragment "
+ f
+ " for a container view with no id"));
}
container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
if (container == null && !f.mRestored) {
String resName;
try {
resName = f.getResources().getResourceName(f.mContainerId);
} catch (Resources.NotFoundException e) {
resName = "unknown";
}
throwException(new IllegalArgumentException(
"No view found for id 0x"
+ Integer.toHexString(f.mContainerId) + " ("
+ resName
+ ") for fragment " + f));
}
}
f.mContainer = container;
//调用performCreateView,最终会调用Fragment的onCreateView方法,
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
f.mView.setSaveFromParentEnabled(false);
if (container != null) {
container.addView(f.mView);
}
if (f.mHidden) {
f.mView.setVisibility(View.GONE);
}
//调用Fragment的onViewCreated方法
f.onViewCreated(f.mView, f.mSavedFragmentState);
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
false);
// Only animate the view if it is visible. This is done after
// dispatchOnFragmentViewCreated in case visibility is changed
f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
&& f.mContainer != null;
} else {
f.mInnerView = null;
}
}
//该方法方法会将mState置为 ACTIVITY_CREATED,然后调用Fragemnt的onActivityCreated,
f.performActivityCreated(f.mSavedFragmentState);
dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
// fall through
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
//该方法最终会调用Frament的onStart方法,并将mState置为STARTED
f.performStart();
dispatchOnFragmentStarted(f, false);
}
// fall through
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
//最终调用Fragment的onReumse方法,将mState置为RESUMED
f.performResume();
dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
需要说明的有如下几点:
1.每次case都没有break,也就是说所有的case语句都会执行到
2.每个case都能调用Fragment的相关声明周期方法
3.每个case中都会对当前的Fragment的mState与需要设置的state(nextState)进行比对,如果当前的nextState等于Fragment的mState则不再进入相关case的if语句(但仍会进入先关的case语句)
这也就说明了Activity每执行一个生命周期都将让该Activity的相关mAdded的fragment回调对应的生命周期。其对应关系如下:
如果Activity执行onPause的话,会进入到FragmentActivity的dispatchPause
protected void onPause() {
super.onPause();
mResumed = false;
//执行FragmentHostCallBack的dispatchPause方法
mFragments.dispatchPause();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
FragmentHostCallBack.dispatchPause
public void dispatchPause() {
//调用FragmentManagerImpl的dispatchPause方法
mHost.mFragmentManager.dispatchPause();
}
FragmentManagerImpl.dispatchPause
public void dispatchPause() {
dispatchStateChange(Fragment.STARTED);
}
最终仍然会调用到moveToState这一方法,如果此时Fragment为RESUMED状态的话,则会走moveToStated的else代码。else代码与if的代码逻辑上类似,但是每个case语句的if代码块都会让当前Fragment递减直到INITIALIZING。在递减的过程中都会调用Fragment的相关生命周期方法。
总结一下FragmentManagerImpl的moveToState方法:
1.首先Fragment创建时默认为INITIALIZING
2.Activity调用相关的生命周期会调用Fragment的dispatchXXXX方法,该方法最终会调用到FragmentManagerImpl的moveToState方法,该方法会比较当前分发的状态与Fragment的当前状态,如果当前Fragment状态小于分发的状态则会走if代码块,否则会走else代码块。
3.在每个switch的case块中都没有break,依旧是要遍历所有的case代码块,但如果当前fragment的状态小于等于分发的状态时才会执行相关case中的if代码块,调用相关的fragment声明周期。大于时则走else的代码块,逻辑与if代码块类似,只是Fragment的mState会依次减少
4.if:Fragment的mState自增(onCretae---》onResumse),else:Fragment的mState自减(onResume---->>onDestory)
流程图总结如下: