Activity與Fragment的生命周期是一個(gè)老生常談的話題,網(wǎng)上最常見的圖是這個(gè):

還有這個(gè):

但是這個(gè)圖并沒有說明Activity和Fragment的每個(gè)階段下,是Fragment的方法先調(diào)用還是Activity的方法先調(diào)用。于是我嘗試了探究了一下。
場(chǎng)景一
我的代碼如下:
Activity1.java
public class Activity1 extends AppCompatActivity {
FragmentManager fragmentManager;
FrameLayout frameLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
log("onCreate");
setContentView(R.layout.activity_simple);
frameLayout = (FrameLayout) findViewById(R.id.container);
fragmentManager = getSupportFragmentManager();
if (savedInstanceState == null) {
fragmentManager.beginTransaction()
.add(R.id.container,SimpleFragment1.getInstance("fragment") , "fragment")
.commit();
}
}
@Override
protected void onStart() {
super.onStart();
log("onStart");
frameLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@Override
protected void onResume() {
super.onResume();
log("onResume");
}
@Override
protected void onPause() {
super.onPause();
log("onPause");
}
@Override
protected void onStop() {
super.onStop();
log("onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
log("onDestroy");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
log("onSaveInstanceState");
}
private void log(String s) {
Log.i("tag", "Activity1 -- " + s);
}
}
SimpleFragment1.java
public class SimpleFragment1 extends Fragment {
private String str;
private int num=1;
public SimpleFragment1() {
}
public static SimpleFragment1 getInstance(String s) {
SimpleFragment1 fragment = new SimpleFragment1();
Bundle b = new Bundle();
b.putString("string", s);
fragment.setArguments(b);
return fragment;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
log("onAttach");
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
log("onCreate");
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
log("onCreateView");
str = getArguments().getString("string");
View v = inflater.inflate(R.layout.fragment_simple, container,false);
TextView text = (TextView) v.findViewById(R.id.textview);
text.setText(str);
return v;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
log("onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
log("onStart");
}
@Override
public void onResume() {
super.onResume();
log("onResume");
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
log("onSaveInstanceState");
}
@Override
public void onPause() {
super.onPause();
log("onPause");
}
@Override
public void onStop() {
super.onStop();
log("onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
log("onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
log("onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
log("onDetach");
}
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
log("isHidden:" + hidden);
}
private void log(String s) {
Log.v("tag","Fragment"+num +" -- " + s);
}
}
布局:
activity_simple.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
fragment_simple.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:textSize="20sp" />
</RelativeLayout>
啟動(dòng)Activity時(shí),生命周期函數(shù)調(diào)用如下:

當(dāng)按鎖屏鍵、 多任務(wù)鍵或者直接按桌面鍵進(jìn)入桌面時(shí),這種情況我暫且稱之為Activity掛起狀態(tài) ,這種情況下生命周期函數(shù)調(diào)用如下:

當(dāng)Activity從后臺(tái)返回(再次按鎖屏鍵打開屏幕,或從多任務(wù)界面回到當(dāng)前應(yīng)用程序界面)時(shí),這種情況暫且稱為掛起-喚醒 狀態(tài)。生命周期函數(shù)調(diào)用如下:

當(dāng)Activity銷毀時(shí):

當(dāng)旋轉(zhuǎn)屏幕時(shí),Activity和Fragment會(huì)被銷毀,然后再重建:

注意,上面的場(chǎng)景是,我在Activity的生命周期函數(shù)中super調(diào)用部分之后在打印log的。
場(chǎng)景二
于是我又做了這樣的實(shí)驗(yàn),我將log打印語句放在super之前,我將Activity的代碼改為這樣(其他代碼不變):
Activity2.java
public class Activity2 extends AppCompatActivity {
FragmentManager fragmentManager;
FrameLayout frameLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
//在super之前打印log
log("onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
frameLayout = (FrameLayout) findViewById(R.id.container);
fragmentManager = getSupportFragmentManager();
if (savedInstanceState == null) {
fragmentManager.beginTransaction()
.add(R.id.container,SimpleFragment1.getInstance("fragment") , "fragment")
.commit();
}
}
@Override
protected void onStart() {
log("onStart");
super.onStart();
frameLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@Override
protected void onResume() {
log("onResume");
super.onResume();
}
@Override
protected void onPause() {
log("onPause");
super.onPause();
}
@Override
protected void onStop() {
log("onStop");
super.onStop();
}
@Override
protected void onDestroy() {
log("onDestroy");
super.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
log("onSaveInstanceState");
super.onSaveInstanceState(outState);
}
private void log(String s) {
Log.i("tag", "Activity2 -- " + s);
}
}
Activity創(chuàng)建時(shí),生命周期函數(shù)調(diào)用如下:

Activity掛起時(shí):

注意:與場(chǎng)景一不同,場(chǎng)景一是先打印了Fragment的生命周期函數(shù),再打印了對(duì)應(yīng)Activity的生命周期函數(shù)。在場(chǎng)景二下,是先打印了Activity的
onPause再打印Fragment的onPause,onSaveInstanceState和onStop都是先打印了Activity再打印Fragment的。
說明Activity中的這個(gè)super.onXXXX從一定程度上與Fragment的生命周期相關(guān)。后面繼續(xù)分析此處
先看在場(chǎng)景二下,Activity的掛起-喚醒狀態(tài):

Activity的銷毀:

旋轉(zhuǎn)屏幕:

可以看到,在場(chǎng)景二下,logcat中打印的消息告訴我們,每個(gè)生命周期階段,都是Activity的生命周期函數(shù)先執(zhí)行,然后再執(zhí)行Fragment的。
Activity生命周期中的super.onXXX與Fragment的關(guān)系分析
以Activity1中onCreate的super.onCreate(savedInstanceState)為例分析:
因?yàn)槲业腁ctivity1繼承自AppCompatActivity,AppCompatActivity的onCreate如下:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
final AppCompatDelegate delegate = getDelegate();
delegate.installViewFactory();
delegate.onCreate(savedInstanceState);
if (delegate.applyDayNight() && mThemeId != 0) {
// If DayNight has been applied, we need to re-apply the theme for
// the changes to take effect. On API 23+, we should bypass
// setTheme(), which will no-op if the theme ID is identical to the
// current theme ID.
if (Build.VERSION.SDK_INT >= 23) {
onApplyThemeResource(getTheme(), mThemeId, false);
} else {
setTheme(mThemeId);
}
}
super.onCreate(savedInstanceState);
}
在最后又調(diào)用了super.onCreate(savedInstanceState),而AppCompatActivity是繼承自FragmentActivity的,所以可以看出與Fragment一定存在某種聯(lián)系。
FragmentActivity的onCreate
protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragments.attachHost(null /*parent*/);
super.onCreate(savedInstanceState);
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
mFragments.restoreLoaderNonConfig(nc.loaders);
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
// Check if there are any pending onActivityResult calls to descendent Fragments.
if (savedInstanceState.containsKey(NEXT_CANDIDATE_REQUEST_INDEX_TAG)) {
mNextCandidateRequestIndex =
savedInstanceState.getInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG);
int[] requestCodes = savedInstanceState.getIntArray(ALLOCATED_REQUEST_INDICIES_TAG);
String[] fragmentWhos = savedInstanceState.getStringArray(REQUEST_FRAGMENT_WHO_TAG);
if (requestCodes == null || fragmentWhos == null ||
requestCodes.length != fragmentWhos.length) {
Log.w(TAG, "Invalid requestCode mapping in savedInstanceState.");
} else {
mPendingFragmentActivityResults = new SparseArrayCompat<>(requestCodes.length);
for (int i = 0; i < requestCodes.length; i++) {
mPendingFragmentActivityResults.put(requestCodes[i], fragmentWhos[i]);
}
}
}
}
if (mPendingFragmentActivityResults == null) {
mPendingFragmentActivityResults = new SparseArrayCompat<>();
mNextCandidateRequestIndex = 0;
}
mFragments.dispatchCreate();
}
最后一句mFragments.dispatchCreate();,mFragments是一個(gè)FragmentController 。 FragmentController是Activity中所有Fragment的生命周期管理者。其dispatchCreate如下:
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
mFragmentManager是一個(gè)FragmentManagerImpl類的實(shí)例,FragmentManagerImpl繼承自FragmentManager類。這里我們把mFragmentManager看成是Fragment的存放容器就可以了。
dispatchCreate()的實(shí)現(xiàn)如下:
public void dispatchCreate() {
mStateSaved = false;
mExecutingActions = true;
moveToState(Fragment.CREATED, false);
mExecutingActions = false;
}
moveToState()的實(shí)現(xiàn)如下,部分代碼省略:
void moveToState(int newState, boolean always) {
.......
mCurState = newState;
if (mActive != null) {
boolean loadersRunning = false;
// Must add them in the proper order. mActive fragments may be out of order
if (mAdded != null) {
final int numAdded = mAdded.size();
for (int i = 0; i < numAdded; i++) {
Fragment f = mAdded.get(i);
//標(biāo)記處1
moveFragmentToExpectedState(f);
if (f.mLoaderManager != null) {
loadersRunning |= f.mLoaderManager.hasRunningLoaders();
}
}
}
// Now iterate through all active fragments. These will include those that are removed
// and detached.
final int numActive = mActive.size();
for (int i = 0; i < numActive; i++) {
Fragment f = mActive.get(i);
if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
//標(biāo)記處2
moveFragmentToExpectedState(f);
if (f.mLoaderManager != null) {
loadersRunning |= f.mLoaderManager.hasRunningLoaders();
}
}
}
.......
}
}
(在上面代碼片段中我做了兩個(gè)標(biāo)記處,后面接著分析這兩處)
moveToState中又調(diào)用了moveFragmentToExpectedState(),從函數(shù)名可知,實(shí)際做的就是將每個(gè)fragment都轉(zhuǎn)移到各自對(duì)應(yīng)的狀態(tài)。
Fragment定義了如下幾種狀態(tài):
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.
初始時(shí)Fragment是位于INITIALIZING 狀態(tài)。
moveFragmentToExpectedState(Fragment f)函數(shù):
void moveFragmentToExpectedState(Fragment f) {
....
moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
if (f.mView != null) {
// Move the view if it is out of order
Fragment underFragment = findFragmentUnder(f);
if (underFragment != null) {
final View underView = underFragment.mView;
// make sure this fragment is in the right order.
final ViewGroup container = f.mContainer;
int underIndex = container.indexOfChild(underView);
int viewIndex = container.indexOfChild(f.mView);
if (viewIndex < underIndex) {
container.removeViewAt(viewIndex);
container.addView(f.mView, underIndex);
}
}
...
}
}
其中調(diào)用了moveToState(Fragment f, int newState, int transit, int transitionStyle,boolean keepActive)。moveToState函數(shù)較長(zhǎng),該函數(shù)我把它稱為關(guān)鍵函數(shù)吧,部分代碼省略:
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
// Fragments that are not currently added will sit in the onCreate() state.
if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
newState = Fragment.CREATED;
}
.....
if (f.mState < newState) {
....
switch (f.mState) {
case Fragment.INITIALIZING:
....
//1.在這里調(diào)用了Fragment的onAttach()
f.onAttach(mHost.getContext());
...
dispatchOnFragmentAttached(f, mHost.getContext(), false);
if (!f.mRetaining) {
//2.在performCreate內(nèi)部調(diào)用了Fragment的onCreate()
f.performCreate(f.mSavedFragmentState);
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
//*****注意:這里將Fragment的狀態(tài)設(shè)置為CREATED
f.mState = Fragment.CREATED;
}
f.mRetaining = false;
if (f.mFromLayout) {
//3.在performCreateView中調(diào)用了Fragment的onCreateView()
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
if (Build.VERSION.SDK_INT >= 11) {
ViewCompat.setSaveFromParentEnabled(f.mView, false);
} else {
f.mView = NoSaveStateFrameLayout.wrap(f.mView);
}
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;
}
}
....
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
....
//4.在performActivityCreated()中調(diào)用了Fragment的onActivityCreated()
f.performActivityCreated(f.mSavedFragmentState);
dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
f.mState = Fragment.STOPPED;
}
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
f.performStart();
dispatchOnFragmentStarted(f, false);
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
f.performResume();
dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
} else if (f.mState > newState) {
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
f.performPause();
dispatchOnFragmentPaused(f, false);
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
f.performStop();
dispatchOnFragmentStopped(f, false);
}
case Fragment.STOPPED:
if (newState < Fragment.STOPPED) {
f.performReallyStop();
}
case Fragment.ACTIVITY_CREATED:
.....
case Fragment.CREATED:
.....
}
}
}
該函數(shù)中就是對(duì)Fragment的各種不同的狀態(tài)進(jìn)行處理,一開始Fragment是處于INITIALIZING狀態(tài)的,在INITIALIZING對(duì)應(yīng)的case 語句中,相應(yīng)的調(diào)用了Fragment的onAttach(),onCreate()和onCreateView(),我在代碼中也寫了注釋。在調(diào)用了onCreate之后,同時(shí)Fragment的狀態(tài)會(huì)被設(shè)置為CREATED。
還記得moveToState(int newState, boolean always)中的標(biāo)記處一和標(biāo)記處二嗎,記不得就再回去看看。這兩處標(biāo)記處都是調(diào)用了關(guān)鍵函數(shù)moveToState。我們可以這么理解,標(biāo)記處一的關(guān)鍵函數(shù)是對(duì)INITIALIZING狀態(tài)的Fragment進(jìn)行處理,當(dāng)執(zhí)行完標(biāo)記處一的關(guān)鍵函數(shù)后,F(xiàn)ragment的狀態(tài)被設(shè)置為CREATED,然后到標(biāo)記處二,對(duì)CREATED狀態(tài)的Fragment再進(jìn)行處理。
下面我們分析關(guān)鍵函數(shù)中對(duì)于CREATED狀態(tài)的case語句:
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
....
//在performActivityCreated()中調(diào)用了Fragment的onActivityCreated()
f.performActivityCreated(f.mSavedFragmentState);
dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
在performActivityCreated()函數(shù)中,調(diào)用了Fragment的onActivityCreated():
void performActivityCreated(Bundle savedInstanceState) {
if (mChildFragmentManager != null) {
mChildFragmentManager.noteStateNotSaved();
}
mState = ACTIVITY_CREATED;
mCalled = false;
onActivityCreated(savedInstanceState);
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onActivityCreated()");
}
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchActivityCreated();
}
}
至此,F(xiàn)ragment的創(chuàng)建過程基本完畢,F(xiàn)ragment的創(chuàng)建時(shí)生命周期函數(shù)可以解釋為:在INITIALIZING中執(zhí)行了onAttach(),onCreate()和onCreateView(),在CREATED中執(zhí)行了onActivityCreated()。
其他的Fragment生命周期函數(shù)也和上面分析的onCreate類似,其本質(zhì)都是在關(guān)鍵函數(shù)中對(duì)各種狀態(tài)進(jìn)行處理并觸發(fā)生命周期回調(diào)函數(shù)。
總結(jié)
實(shí)際上同階段下Activity的生命周期函數(shù)是Fragment的生命周期函數(shù)入口,這里同階段是指Activity的onCreate對(duì)應(yīng)Fragment的onCreate,Activity的onResume對(duì)應(yīng)Fragment的onResume之類的。
Activity的super.onXXXX中正是調(diào)用了Fragment的生命周期函數(shù)onXXXX。這也就解釋了場(chǎng)景一和場(chǎng)景二中為什么在不同的地方打印log結(jié)果輸出是不一樣的。
關(guān)于Activity與Fragment的生命周期,github上還有一位大神畫了這樣一張圖,地址在這里:https://github.com/xxv/android-lifecycle
其實(shí)我還有一點(diǎn)沒理解,在場(chǎng)景一中,由于我log語句是寫在super之后的,為啥是Activity1的onResume先執(zhí)行,再執(zhí)行Fragment1的onResume?如果有知道的朋友請(qǐng)告訴我,謝謝。