• Fragment的创建分析


            之前的文章讨论了Fragment的销毁流程,初始状态为resume,然后经历pause -> stop -> destroyView -> destroy -> detach这么几个流程(本篇文章基于Support27.1.1来分析的)。清楚了Fragment的销毁,那也来看看Fragment的创建,这里先放一张Fragment生命周期的图,如下:

            该图包含了Fragment从创建到销毁的所有生命周期方法及与相应Activity生命周期状态的对关系,相应面试过程中如果遇到Fragment相关的问题,应该都不会逃过生命周期相关的问题。然而生命周期只是Fragment运行的表现,它是如何一步步运行起来的呢?这篇文章聚焦Fragment的创建,从源码角度分析Fragment的创建流程。

            由于Fragment的流程依附于相应Activity的生命周期,因此这里以Activity的onCreate、onStart、onResume为主线来说明Fragment的生命周期是如何转换的。

    目录

    1. Activity.onCreate

    2. Activity.onStart

    3. Activity.onResume


    1. Activity.onCreate

            在Activity的onCreate执行的时候,我们的Fragment则经历了onAttach -> onCreate ->onCreateView -> onActivityCreated几个生命周期方法,下面从FragmentActivity的onCreate开始分析,老规矩上代码:

    1. @SuppressWarnings("deprecation")
    2. @Override
    3. protected void onCreate(@Nullable Bundle savedInstanceState) {
    4. mFragments.attachHost(null /*parent*/);//A
    5. super.onCreate(savedInstanceState);
    6. NonConfigurationInstances nc =
    7. (NonConfigurationInstances) getLastNonConfigurationInstance();
    8. if (nc != null) {
    9. mViewModelStore = nc.viewModelStore;
    10. }
    11. if (savedInstanceState != null) {//B
    12. Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
    13. mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
    14. // Check if there are any pending onActivityResult calls to descendent Fragments.
    15. if (savedInstanceState.containsKey(NEXT_CANDIDATE_REQUEST_INDEX_TAG)) {
    16. mNextCandidateRequestIndex =
    17. savedInstanceState.getInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG);
    18. int[] requestCodes = savedInstanceState.getIntArray(ALLOCATED_REQUEST_INDICIES_TAG);
    19. String[] fragmentWhos = savedInstanceState.getStringArray(REQUEST_FRAGMENT_WHO_TAG);
    20. if (requestCodes == null || fragmentWhos == null ||
    21. requestCodes.length != fragmentWhos.length) {
    22. Log.w(TAG, "Invalid requestCode mapping in savedInstanceState.");
    23. } else {
    24. mPendingFragmentActivityResults = new SparseArrayCompat<>(requestCodes.length);
    25. for (int i = 0; i < requestCodes.length; i++) {
    26. mPendingFragmentActivityResults.put(requestCodes[i], fragmentWhos[i]);
    27. }
    28. }
    29. }
    30. }
    31. if (mPendingFragmentActivityResults == null) {
    32. mPendingFragmentActivityResults = new SparseArrayCompat<>();
    33. mNextCandidateRequestIndex = 0;
    34. }
    35. mFragments.dispatchCreate();//C
    36. }

            上面的代码中用注释标识了A/B/C三处代码,A处相当于是Fragment运行环境的初始化,B处是状态的恢复,C处是Fragment生命周期的状态转换;我们重点看A/C两处,先看A,代码如下:

    1. //FragmentActivity.java
    2. final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
    3. //FragmentController.java
    4. /**
    5. * Attaches the host to the FragmentManager for this controller. The host must be
    6. * attached before the FragmentManager can be used to manage Fragments.
    7. */
    8. public void attachHost(Fragment parent) {
    9. mHost.mFragmentManager.attachController(
    10. mHost, mHost /*container*/, parent);
    11. }
    12. //FragmentManager.java
    13. public void attachController(FragmentHostCallback host,
    14. FragmentContainer container, Fragment parent) {
    15. if (mHost != null) throw new IllegalStateException("Already attached");
    16. mHost = host;
    17. mContainer = container;
    18. mParent = parent;
    19. }

             调用attachHost把相关参数传递到FragmentManager中,mHost、mContainer的值都为在FragmentActivity中创建的HostCallbacks对象,mParent则为空,Activity中的第一个Fragment的mParentFragment对象总是空的,因为它就是第一个Fragment。

            mFragments.dispatchCreate()这行代码开启了Fragment生命周期的轮转,经过前面的分析我们知道最终会到FragmentManager中5个参数版本的moveToState方法中,这里简单贴下中间跳转代码:

    1. /**
    2. * Moves all Fragments managed by the controller's FragmentManager
    3. * into the create state.
    4. *

      Call when Fragments should be created.

    5. *
    6. * @see Fragment#onCreate(Bundle)
    7. */
    8. public void dispatchCreate() {
    9. mHost.mFragmentManager.dispatchCreate();
    10. }
    11. public void dispatchCreate() {
    12. mStateSaved = false;
    13. mStopped = false;
    14. dispatchStateChange(Fragment.CREATED);//注意该值
    15. }
    16. private void dispatchStateChange(int nextState) {
    17. try {
    18. mExecutingActions = true;
    19. moveToState(nextState, false);
    20. } finally {
    21. mExecutingActions = false;
    22. }
    23. execPendingActions();
    24. }
    25. void moveToState(int newState, boolean always) {
    26. if (mHost == null && newState != Fragment.INITIALIZING) {
    27. throw new IllegalStateException("No activity");
    28. }
    29. if (!always && newState == mCurState) {
    30. return;
    31. }
    32. mCurState = newState;
    33. if (mActive != null) {
    34. // Must add them in the proper order. mActive fragments may be out of order
    35. final int numAdded = mAdded.size();
    36. for (int i = 0; i < numAdded; i++) {
    37. Fragment f = mAdded.get(i);
    38. moveFragmentToExpectedState(f);
    39. }
    40. // Now iterate through all active fragments. These will include those that are removed
    41. // and detached.
    42. final int numActive = mActive.size();
    43. for (int i = 0; i < numActive; i++) {
    44. Fragment f = mActive.valueAt(i);
    45. if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
    46. moveFragmentToExpectedState(f);
    47. }
    48. }
    49. startPendingDeferredFragments();
    50. if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
    51. mHost.onSupportInvalidateOptionsMenu();
    52. mNeedMenuInvalidate = false;
    53. }
    54. }
    55. }
    56. void moveFragmentToExpectedState(Fragment f) {
    57. if (f == null) {
    58. return;
    59. }
    60. int nextState = mCurState;
    61. if (f.mRemoving) {
    62. if (f.isInBackStack()) {
    63. nextState = Math.min(nextState, Fragment.CREATED);
    64. } else {
    65. nextState = Math.min(nextState, Fragment.INITIALIZING);
    66. }
    67. }
    68. moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);//状态转换入口
    69. if (f.mView != null) {
    70. // Move the view if it is out of order
    71. Fragment underFragment = findFragmentUnder(f);
    72. if (underFragment != null) {
    73. final View underView = underFragment.mView;
    74. // make sure this fragment is in the right order.
    75. final ViewGroup container = f.mContainer;
    76. int underIndex = container.indexOfChild(underView);
    77. int viewIndex = container.indexOfChild(f.mView);
    78. if (viewIndex < underIndex) {
    79. container.removeViewAt(viewIndex);
    80. container.addView(f.mView, underIndex);
    81. }
    82. }
    83. if (f.mIsNewlyAdded && f.mContainer != null) {
    84. // Make it visible and run the animations
    85. if (f.mPostponedAlpha > 0f) {
    86. f.mView.setAlpha(f.mPostponedAlpha);
    87. }
    88. f.mPostponedAlpha = 0f;
    89. f.mIsNewlyAdded = false;
    90. // run animations:
    91. AnimationOrAnimator anim = loadAnimation(f, f.getNextTransition(), true,
    92. f.getNextTransitionStyle());
    93. if (anim != null) {
    94. setHWLayerAnimListenerIfAlpha(f.mView, anim);
    95. if (anim.animation != null) {
    96. f.mView.startAnimation(anim.animation);
    97. } else {
    98. anim.animator.setTarget(f.mView);
    99. anim.animator.start();
    100. }
    101. }
    102. }
    103. }
    104. if (f.mHiddenChanged) {
    105. completeShowHideFragment(f);
    106. }
    107. }

            嗯,一堆堆代码了,moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false); 最后这行代码正式进入生命周期转换当中,通过前面的分析知道分为创建和销毁两大流程,这里省略销毁流程,创建流程代码如下:

    1. @SuppressWarnings("ReferenceEquality")
    2. void moveToState(Fragment f, int newState, int transit, int transitionStyle,
    3. boolean keepActive) {
    4. // Fragments that are not currently added will sit in the onCreate() state.
    5. if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
    6. newState = Fragment.CREATED;
    7. }
    8. if (f.mRemoving && newState > f.mState) {
    9. if (f.mState == Fragment.INITIALIZING && f.isInBackStack()) {
    10. // Allow the fragment to be created so that it can be saved later.
    11. newState = Fragment.CREATED;
    12. } else {
    13. // While removing a fragment, we can't change it to a higher state.
    14. newState = f.mState;
    15. }
    16. }
    17. // Defer start if requested; don't allow it to move to STARTED or higher
    18. // if it's not already started.
    19. if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
    20. newState = Fragment.STOPPED;
    21. }
    22. if (f.mState <= newState) {
    23. //这里是创建流程 attach -> create -> creatView -> activityCreated ->
    24. // start -> resume
    25. // For fragments that are created from a layout, when restoring from
    26. // state we don't want to allow them to be created until they are
    27. // being reloaded from the layout.
    28. if (f.mFromLayout && !f.mInLayout) {
    29. return;
    30. }
    31. if (f.getAnimatingAway() != null || f.getAnimator() != null) {
    32. // The fragment is currently being animated... but! Now we
    33. // want to move our state back up. Give up on waiting for the
    34. // animation, move to whatever the final state should be once
    35. // the animation is done, and then we can proceed from there.
    36. f.setAnimatingAway(null);
    37. f.setAnimator(null);
    38. moveToState(f, f.getStateAfterAnimating(), 0, 0, true);
    39. }
    40. switch (f.mState) {
    41. case Fragment.INITIALIZING:
    42. if (newState > Fragment.INITIALIZING) {
    43. if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
    44. if (f.mSavedFragmentState != null) {
    45. f.mSavedFragmentState.setClassLoader(mHost.getContext()
    46. .getClassLoader());
    47. f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
    48. FragmentManagerImpl.VIEW_STATE_TAG);
    49. f.mTarget = getFragment(f.mSavedFragmentState,
    50. FragmentManagerImpl.TARGET_STATE_TAG);
    51. if (f.mTarget != null) {
    52. f.mTargetRequestCode = f.mSavedFragmentState.getInt(
    53. FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
    54. }
    55. if (f.mSavedUserVisibleHint != null) {
    56. f.mUserVisibleHint = f.mSavedUserVisibleHint;
    57. f.mSavedUserVisibleHint = null;
    58. } else {
    59. f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
    60. FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
    61. }
    62. if (!f.mUserVisibleHint) {
    63. f.mDeferStart = true;
    64. if (newState > Fragment.STOPPED) {
    65. newState = Fragment.STOPPED;
    66. }
    67. }
    68. }
    69. f.mHost = mHost;
    70. f.mParentFragment = mParent;
    71. f.mFragmentManager = mParent != null
    72. ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
    73. // If we have a target fragment, push it along to at least CREATED
    74. // so that this one can rely on it as an initialized dependency.
    75. if (f.mTarget != null) {
    76. if (mActive.get(f.mTarget.mIndex) != f.mTarget) {
    77. throw new IllegalStateException("Fragment " + f
    78. + " declared target fragment " + f.mTarget
    79. + " that does not belong to this FragmentManager!");
    80. }
    81. if (f.mTarget.mState < Fragment.CREATED) {
    82. moveToState(f.mTarget, Fragment.CREATED, 0, 0, true);
    83. }
    84. }
    85. dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
    86. f.mCalled = false;
    87. f.onAttach(mHost.getContext());
    88. if (!f.mCalled) {
    89. throw new SuperNotCalledException("Fragment " + f
    90. + " did not call through to super.onAttach()");
    91. }
    92. if (f.mParentFragment == null) {
    93. mHost.onAttachFragment(f);
    94. } else {
    95. f.mParentFragment.onAttachFragment(f);
    96. }
    97. dispatchOnFragmentAttached(f, mHost.getContext(), false);
    98. if (!f.mIsCreated) {
    99. dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
    100. f.performCreate(f.mSavedFragmentState);
    101. dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
    102. } else {
    103. f.restoreChildFragmentState(f.mSavedFragmentState);
    104. f.mState = Fragment.CREATED;
    105. }
    106. f.mRetaining = false;
    107. }
    108. // fall through
    109. case Fragment.CREATED:
    110. // This is outside the if statement below on purpose; we want this to run
    111. // even if we do a moveToState from CREATED => *, CREATED => CREATED, and
    112. // * => CREATED as part of the case fallthrough above.
    113. ensureInflatedFragmentView(f);
    114. if (newState > Fragment.CREATED) {
    115. if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
    116. if (!f.mFromLayout) {
    117. ViewGroup container = null;
    118. if (f.mContainerId != 0) {
    119. if (f.mContainerId == View.NO_ID) {
    120. throwException(new IllegalArgumentException(
    121. "Cannot create fragment "
    122. + f
    123. + " for a container view with no id"));
    124. }
    125. container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
    126. if (container == null && !f.mRestored) {
    127. String resName;
    128. try {
    129. resName = f.getResources().getResourceName(f.mContainerId);
    130. } catch (NotFoundException e) {
    131. resName = "unknown";
    132. }
    133. throwException(new IllegalArgumentException(
    134. "No view found for id 0x"
    135. + Integer.toHexString(f.mContainerId) + " ("
    136. + resName
    137. + ") for fragment " + f));
    138. }
    139. }
    140. f.mContainer = container;
    141. f.mView = f.performCreateView(f.performGetLayoutInflater(
    142. f.mSavedFragmentState), container, f.mSavedFragmentState);
    143. if (f.mView != null) {
    144. f.mInnerView = f.mView;
    145. f.mView.setSaveFromParentEnabled(false);
    146. if (container != null) {
    147. container.addView(f.mView);
    148. }
    149. if (f.mHidden) {
    150. f.mView.setVisibility(View.GONE);
    151. }
    152. f.onViewCreated(f.mView, f.mSavedFragmentState);
    153. dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
    154. false);
    155. // Only animate the view if it is visible. This is done after
    156. // dispatchOnFragmentViewCreated in case visibility is changed
    157. f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
    158. && f.mContainer != null;
    159. } else {
    160. f.mInnerView = null;
    161. }
    162. }
    163. f.performActivityCreated(f.mSavedFragmentState);
    164. dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
    165. if (f.mView != null) {
    166. f.restoreViewState(f.mSavedFragmentState);
    167. }
    168. f.mSavedFragmentState = null;
    169. }
    170. // fall through
    171. case Fragment.ACTIVITY_CREATED:
    172. if (newState > Fragment.ACTIVITY_CREATED) {
    173. f.mState = Fragment.STOPPED;
    174. }
    175. // fall through
    176. case Fragment.STOPPED:
    177. if (newState > Fragment.STOPPED) {
    178. if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
    179. f.performStart();
    180. dispatchOnFragmentStarted(f, false);
    181. }
    182. // fall through
    183. case Fragment.STARTED:
    184. if (newState > Fragment.STARTED) {
    185. if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
    186. f.performResume();
    187. dispatchOnFragmentResumed(f, false);
    188. f.mSavedFragmentState = null;
    189. f.mSavedViewState = null;
    190. }
    191. }
    192. } else if (f.mState > newState) {
    193. //这里是销毁流程 pause -> stop -> destoroyView -> destory -> detach
    194. }
    195. if (f.mState != newState) {
    196. Log.w(TAG, "moveToState: Fragment state for " + f + " not updated inline; "
    197. + "expected state " + newState + " found " + f.mState);
    198. f.mState = newState;
    199. }
    200. }

            首次进入Fragment的状态为Fragment.INITIALIZING,而前面调用dispatchCreate 时传递的状态nextState参数为Fragment.CREATED,因此newState为Fragment.CREATED,所以上面的创建流程会进入到Fragment.INITIALIZING对应的分支,这里单独拿出该分支代码如下:

    1. if (newState > Fragment.INITIALIZING) {
    2. if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
    3. if (f.mSavedFragmentState != null) {//A
    4. f.mSavedFragmentState.setClassLoader(mHost.getContext()
    5. .getClassLoader());
    6. f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
    7. FragmentManagerImpl.VIEW_STATE_TAG);
    8. f.mTarget = getFragment(f.mSavedFragmentState,
    9. FragmentManagerImpl.TARGET_STATE_TAG);
    10. if (f.mTarget != null) {
    11. f.mTargetRequestCode = f.mSavedFragmentState.getInt(
    12. FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
    13. }
    14. if (f.mSavedUserVisibleHint != null) {
    15. f.mUserVisibleHint = f.mSavedUserVisibleHint;
    16. f.mSavedUserVisibleHint = null;
    17. } else {
    18. f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
    19. FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
    20. }
    21. if (!f.mUserVisibleHint) {
    22. f.mDeferStart = true;
    23. if (newState > Fragment.STOPPED) {
    24. newState = Fragment.STOPPED;
    25. }
    26. }
    27. }
    28. //B
    29. f.mHost = mHost;
    30. f.mParentFragment = mParent;
    31. f.mFragmentManager = mParent != null
    32. ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
    33. // If we have a target fragment, push it along to at least CREATED
    34. // so that this one can rely on it as an initialized dependency.
    35. if (f.mTarget != null) {
    36. if (mActive.get(f.mTarget.mIndex) != f.mTarget) {
    37. throw new IllegalStateException("Fragment " + f
    38. + " declared target fragment " + f.mTarget
    39. + " that does not belong to this FragmentManager!");
    40. }
    41. if (f.mTarget.mState < Fragment.CREATED) {
    42. moveToState(f.mTarget, Fragment.CREATED, 0, 0, true);
    43. }
    44. }
    45. //C
    46. dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
    47. f.mCalled = false;
    48. f.onAttach(mHost.getContext());
    49. if (!f.mCalled) {
    50. throw new SuperNotCalledException("Fragment " + f
    51. + " did not call through to super.onAttach()");
    52. }
    53. if (f.mParentFragment == null) {
    54. mHost.onAttachFragment(f);
    55. } else {
    56. f.mParentFragment.onAttachFragment(f);
    57. }
    58. dispatchOnFragmentAttached(f, mHost.getContext(), false);
    59. if (!f.mIsCreated) {//D
    60. dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
    61. f.performCreate(f.mSavedFragmentState);
    62. dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
    63. } else {
    64. f.restoreChildFragmentState(f.mSavedFragmentState);
    65. f.mState = Fragment.CREATED;
    66. }
    67. f.mRetaining = false;
    68. }

            上面的代码标注了A/B/C/D四处,A处主要是状态恢复,B处mHost、mParentFragment、mFragmentManager的赋值,C处调用了生命周期方法onAttach,D处则调用了onCreate,这里关注C/D两处,先看C处代码如下:

    1. /**
    2. * Called when a fragment is first attached to its context.
    3. * {@link #onCreate(Bundle)} will be called after this.
    4. */
    5. @CallSuper
    6. public void onAttach(Context context) {
    7. mCalled = true;
    8. final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    9. if (hostActivity != null) {
    10. mCalled = false;
    11. onAttach(hostActivity);
    12. }
    13. }

            简单的调用了 onAttach而已。

    tips:这里的onAttach方法有两个版本,一个是带Context参数的,一个是带Activity参数的,其实通过代码分析发现传递过来的始终是Activity对象。

            再看D处,代码如下:

    1. void performCreate(Bundle savedInstanceState) {
    2. if (mChildFragmentManager != null) {
    3. mChildFragmentManager.noteStateNotSaved();
    4. }
    5. mState = CREATED;
    6. mCalled = false;
    7. onCreate(savedInstanceState);
    8. mIsCreated = true;
    9. if (!mCalled) {
    10. throw new SuperNotCalledException("Fragment " + this
    11. + " did not call through to super.onCreate()");
    12. }
    13. mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    14. }
    15. @CallSuper
    16. public void onCreate(@Nullable Bundle savedInstanceState) {
    17. mCalled = true;
    18. restoreChildFragmentState(savedInstanceState);
    19. if (mChildFragmentManager != null
    20. && !mChildFragmentManager.isStateAtLeast(Fragment.CREATED)) {
    21. mChildFragmentManager.dispatchCreate();
    22. }
    23. }

             也是简单回调,同时重置mIsCreated为true(避免重复调用吧),注意这里也会调用恢复子Fragment的状态。

    onCreate调用完毕,Fragment的mState为CREATED,相应FragmentManager内部的mCurState为CREATED。

             Fragment的onCreate调用完毕,继续运行;switch代码穿透到Fragment.CREATED分支,这里根据Fragment和相应FragmentManager的状态对比,并不会进入该分支的if语句内部(表明当前执行到了Fragment.CREATED这个状态)。但是以下代码会执行:

    1. void ensureInflatedFragmentView(Fragment f) {
    2. if (f.mFromLayout && !f.mPerformedCreateView) {
    3. f.mView = f.performCreateView(f.performGetLayoutInflater(
    4. f.mSavedFragmentState), null, f.mSavedFragmentState);
    5. if (f.mView != null) {
    6. f.mInnerView = f.mView;
    7. f.mView.setSaveFromParentEnabled(false);
    8. if (f.mHidden) f.mView.setVisibility(View.GONE);
    9. f.onViewCreated(f.mView, f.mSavedFragmentState);
    10. dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
    11. } else {
    12. f.mInnerView = null;
    13. }
    14. }
    15. }

            如果Fragment是在布局中加载的,这里就会创建Fragment的View了,这里假设不是,我们继续分析。

            Activity.onCreate执行完毕,发现只调用了相应Fragment的onAttach和onCreate方法,貌似与开篇上的图有差别(知道就行了,别怪我的图,我也是不知道从哪里拿来的)。 

    2. Activity.onStart

            现在进入Activity的onStart方法,代码如下:

    1. @Override
    2. protected void onStart() {
    3. super.onStart();
    4. mStopped = false;
    5. mReallyStopped = false;
    6. mHandler.removeMessages(MSG_REALLY_STOPPED);
    7. if (!mCreated) {
    8. mCreated = true;
    9. mFragments.dispatchActivityCreated();//A
    10. }
    11. mFragments.noteStateNotSaved();
    12. mFragments.execPendingActions();
    13. // NOTE: HC onStart goes here.
    14. mFragments.dispatchStart();//B
    15. }

            关注A/B两处,这里的状态分发都会进入到FragmentManager里面5个参数的moveToState方法中,所以中间的过程省略了。

            先看A处,还是关注传递的参数,代码如下:

    1. public void dispatchActivityCreated() {
    2. mStateSaved = false;
    3. mStopped = false;
    4. dispatchStateChange(Fragment.ACTIVITY_CREATED);
    5. }

             这里传递了Fragment.ACTIVITY_CREATED,因此FragmengManager中mCurState会变为Fragment.ACTIVITY_CREATED,但是相应Fragment的状态mState还是CREATED(即将要变为ACTIVITY_CREATED),所以进入到moveToState的Fragment.CREATED分支中,代码如下:

    1. // This is outside the if statement below on purpose; we want this to run
    2. // even if we do a moveToState from CREATED => *, CREATED => CREATED, and
    3. // * => CREATED as part of the case fallthrough above.
    4. ensureInflatedFragmentView(f);
    5. if (newState > Fragment.CREATED) {
    6. if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
    7. if (!f.mFromLayout) {
    8. ViewGroup container = null;
    9. if (f.mContainerId != 0) {//A
    10. if (f.mContainerId == View.NO_ID) {
    11. throwException(new IllegalArgumentException(
    12. "Cannot create fragment " + f
    13. + " for a container view with no id"));
    14. }
    15. container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
    16. if (container == null && !f.mRestored) {
    17. String resName;
    18. try {
    19. resName = f.getResources().getResourceName(f.mContainerId);
    20. } catch (Resources.NotFoundException e) {
    21. resName = "unknown";
    22. }
    23. throwException(new IllegalArgumentException(
    24. "No view found for id 0x"
    25. + Integer.toHexString(f.mContainerId) + " ("
    26. + resName
    27. + ") for fragment " + f));
    28. }
    29. }
    30. //B
    31. f.mContainer = container;
    32. f.mView = f.performCreateView(f.performGetLayoutInflater(
    33. f.mSavedFragmentState), container, f.mSavedFragmentState);
    34. if (f.mView != null) {
    35. f.mInnerView = f.mView;
    36. f.mView.setSaveFromParentEnabled(false);
    37. if (container != null) {
    38. container.addView(f.mView);
    39. }
    40. if (f.mHidden) {
    41. f.mView.setVisibility(View.GONE);
    42. }
    43. //C
    44. f.onViewCreated(f.mView, f.mSavedFragmentState);
    45. dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
    46. false);
    47. // Only animate the view if it is visible. This is done after
    48. // dispatchOnFragmentViewCreated in case visibility is changed
    49. f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
    50. && f.mContainer != null;
    51. } else {
    52. f.mInnerView = null;
    53. }
    54. }
    55. //D
    56. f.performActivityCreated(f.mSavedFragmentState);
    57. dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
    58. if (f.mView != null) {
    59. f.restoreViewState(f.mSavedFragmentState);
    60. }
    61. f.mSavedFragmentState = null;
    62. }

            ensureInflatedFragmentView已经分析过,不再说明; 上面的代码标记了A/B/C/D四处,这里会一一说明,A处主要是找到相应activity中Fragment的容器View,如果找不到则会抛异常。

    我们通过如下代码动态添加Fragment

    1. FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    2. ft.add(R.id.container, new FragmentLifeTest(), "FragmentLifeTest")
    3. .commitAllowingStateLoss();

    上面分析的A处其实就是找到R.id.containe对应的View(该View是相应Fragment的View的容器)

             B处把A处找到的容器保存到Fragment的mContainer成员变量中,接着调用方法performCreateView,该方法会返回Fragment对应的View视图,接着把返回的View视图添加到mContainer中(嗯,Fragment的视图还是通过操作activity中的容器添加到activity视图中的),来看下performCreateView方法,代码如下:

    1. View performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
    2. @Nullable Bundle savedInstanceState) {
    3. if (mChildFragmentManager != null) {
    4. mChildFragmentManager.noteStateNotSaved();
    5. }
    6. mPerformedCreateView = true;
    7. return onCreateView(inflater, container, savedInstanceState);
    8. }

            比较简单,调用onCreateView返回Fragment对应的View,没啥说的。 

            接着分析,来到C处,调用onViewCreated,嗯,这里直接调用了Fragment的onViewCreated方法,传递了刚刚返回的Fragment对应的View,说明此时View已经创建;所以我们再写Fragment的时候通常会把UI的初始化逻辑写在onViewCreated中,这回知道原因了吧。

            最后是D处,performActivityCreated,代码如下:

    1. void performActivityCreated(Bundle savedInstanceState) {
    2. if (mChildFragmentManager != null) {
    3. mChildFragmentManager.noteStateNotSaved();
    4. }
    5. mState = ACTIVITY_CREATED;
    6. mCalled = false;
    7. onActivityCreated(savedInstanceState);
    8. if (!mCalled) {
    9. throw new SuperNotCalledException("Fragment " + this
    10. + " did not call through to super.onActivityCreated()");
    11. }
    12. if (mChildFragmentManager != null) {
    13. mChildFragmentManager.dispatchActivityCreated();
    14. }
    15. }

            也是简单的调用了onActivityCreated,注意这里Fragment状态发生了改变,变为ACTIVITY_CREATED。

    执行完Activity.onStart方法之后,Fragment的状态从CREATED转变为了ACTIVITY_CREATED。

            继续分析 ,CREATED分支执行完毕,代码继续运行,进入ACTIVITY_CREATED分支,经过分析,该分支条件不满足,最后退出整个switch代码块。

    分析完Activity.onStart的第一部分dispatchActivityCreated,我们知道对应的Fragment主要执行了onCreateView -> onViewCreated -> onActivityCreated

            进入 Activity.onStart的第二部分dispatchStart,相关传参代码如下:

    1. public void dispatchStart() {
    2. mStateSaved = false;
    3. mStopped = false;
    4. dispatchStateChange(Fragment.STARTED);
    5. }

            参数为 Fragment.STARTE,则FragmentManager的mCurState会变为Fragment.STARTE,而Fragment此时还是上一个状态即:ACTIVITY_CREATED,因此执行如下代码:

    1. case Fragment.ACTIVITY_CREATED:
    2. if (newState > Fragment.ACTIVITY_CREATED) {
    3. f.mState = Fragment.STOPPED;
    4. }

            太简单了,一个瞬时状态,Fragment的状态直接变为Fragment.STOPPED了,继续分析,由于传递的nextState为Fragment.STARTE,因此进入如下代码:

    1. case Fragment.STOPPED:
    2. if (newState > Fragment.STOPPED) {
    3. if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
    4. f.performStart();
    5. dispatchOnFragmentStarted(f, false);
    6. }
    7. // fall through

            调用了Fragment的performStart方法,该方法代码如下:

    1. void performStart() {
    2. if (mChildFragmentManager != null) {
    3. mChildFragmentManager.noteStateNotSaved();
    4. mChildFragmentManager.execPendingActions();
    5. }
    6. mState = STARTED;
    7. mCalled = false;
    8. onStart();
    9. if (!mCalled) {
    10. throw new SuperNotCalledException("Fragment " + this
    11. + " did not call through to super.onStart()");
    12. }
    13. if (mChildFragmentManager != null) {
    14. mChildFragmentManager.dispatchStart();
    15. }
    16. mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    17. }

             Fragment的状态变为了STARTED,同时调用Fragment的生命周期方法onStart。

            代码继续运行,进入到Fragment.STARTED分支,但是此时条件不满足,因此退出switch代码块。

    总结起来,在activity的onSart生命周期中,相应Fragment调用了经历了:onCreateView -> onViewCreated -> onActivityCreated -> onStart。相应状态mState最终变为了Fragment.STARTED。

    3. Activity.onResume

            到了Activity的onResume阶段,Fragment的创建也快完成了,Activity入口处代码如下:

    1. /**
    2. * Dispatch onResume() to fragments. Note that for better inter-operation
    3. * with older versions of the platform, at the point of this call the
    4. * fragments attached to the activity are not resumed. This means
    5. * that in some cases the previous state may still be saved, not allowing
    6. * fragment transactions that modify the state. To correctly interact
    7. * with fragments in their proper state, you should instead override
    8. * {@link #onResumeFragments()}.
    9. */
    10. @Override
    11. protected void onResume() {
    12. super.onResume();
    13. mHandler.sendEmptyMessage(MSG_RESUME_PENDING);
    14. mResumed = true;
    15. mFragments.execPendingActions();
    16. }

            发送了一个消息去执行Fragment的resume(为啥这里要这样做呢?不太理解,希望有明白的读者不吝指教),MSG_RESUME_PENDING对应的代码如下:

    1. final Handler mHandler = new Handler() {
    2. @Override
    3. public void handleMessage(Message msg) {
    4. switch (msg.what) {
    5. case MSG_REALLY_STOPPED:
    6. if (mStopped) {
    7. doReallyStop(false);
    8. }
    9. break;
    10. case MSG_RESUME_PENDING:
    11. onResumeFragments();
    12. mFragments.execPendingActions();
    13. break;
    14. default:
    15. super.handleMessage(msg);
    16. }
    17. }
    18. };
    19. /**
    20. * This is the fragment-orientated version of {@link #onResume()} that you
    21. * can override to perform operations in the Activity at the same point
    22. * where its fragments are resumed. Be sure to always call through to
    23. * the super-class.
    24. */
    25. protected void onResumeFragments() {
    26. mFragments.dispatchResume();
    27. }

            还是调用mFragments.dispatchResume把Activity相关的事件传递到FragmentManager中进行分发,贴出部分传参的关键代码:

    1. public void dispatchResume() {
    2. mStateSaved = false;
    3. mStopped = false;
    4. dispatchStateChange(Fragment.RESUMED);
    5. }

            这里传递了Fragment.RESUMED,则相应FragmentManager中的mCurState为Fragment.RESUMED,而Fragment还是上一个状态Fragment.STARTED,因此在moveToState方法中会执行如下代码:

    1. // fall through
    2. case Fragment.STARTED:
    3. if (newState > Fragment.STARTED) {
    4. if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
    5. f.performResume();
    6. dispatchOnFragmentResumed(f, false);
    7. f.mSavedFragmentState = null;
    8. f.mSavedViewState = null;
    9. }

            调用perormResume,同时调用dispatchOnFragmentResumed分发resume事件,这里看看perormResume,代码如下:

    1. void performResume() {
    2. if (mChildFragmentManager != null) {
    3. mChildFragmentManager.noteStateNotSaved();
    4. mChildFragmentManager.execPendingActions();
    5. }
    6. mState = RESUMED;
    7. mCalled = false;
    8. onResume();
    9. if (!mCalled) {
    10. throw new SuperNotCalledException("Fragment " + this
    11. + " did not call through to super.onResume()");
    12. }
    13. if (mChildFragmentManager != null) {
    14. mChildFragmentManager.dispatchResume();
    15. mChildFragmentManager.execPendingActions();
    16. }
    17. mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    18. }

            修改Fragment的状态为Fragment.RESUMED,调用onResume生命周期方法,调用通过LifecycleRegistry注册的resume事件。

    执行完Activity.onResume,相应的Fragment状态也变为了Fragment.RESUMED。

            到此,Fragment的创建算是完成了,从源码角度分析了activity中的生命周期对应的Fragment生命周期事件;若是你能读到这里,相信会有所收获。 

  • 相关阅读:
    YoloV8改进策略:聚焦线性注意力重构YoloV8
    js 实现月份的切换,初始化当前月,前进到前一个月份,后退到后一个月份。
    微擎模块 微乐居房产v3.0.9综合版小程序,美化小程序房源详情,增加底部菜单
    使用NSSM将.exe程序安装成windows服务
    Gradle系列【6】生命周期
    深入了解 C 语言 Bug
    leetcode 5229: 拼接数组的最大分数
    WEB攻防-IIS中间件PUT漏洞
    含文档+PPT+源码等]精品微信小程序ssm驾校教培服务系统小程序+后台管理系统|前后分离VUE[包运行成功]微信小程序项目源码Java毕业设计
    玩转Jetson Nano(三):安装Pytorch GPU版
  • 原文地址:https://blog.csdn.net/www586089/article/details/132716125