继续承接上一篇文章----Fragment.OnPause的事情,我们知道onPause之后进入的是onStop生命周期方法,那Fragment的onStop方法又干了些什么呢?
还是从Activity入手,相应的入口代码如下:
//FragmentActivity.java
/**
* Dispatch onStop() to all fragments.
*/
@Override
protected void onStop() {
super.onStop();
mStopped = true;
markFragmentsCreated();
mHandler.sendEmptyMessage(MSG_REALLY_STOPPED);
mFragments.dispatchStop();
}
这里主要做了3个事情,首先调用markFragmentsCreated标记相应fragment的LifecycleRegistry状态,这里不是重点,不关注;其次发送了消息MSG_REALLY_STOPPED;最后调用mFragments.dispatchStop()分发activity的生命周期;这里关注dispatchStop,代码如下:
//FragmentManager.java
public void dispatchStop() {
mStopped = true;
dispatchStateChange(Fragment.STOPPED);
}
private void dispatchStateChange(int nextState) {
try {
mExecutingActions = true;
moveToState(nextState, false);
} finally {
mExecutingActions = false;
}
execPendingActions();
}
/**
* Changes the state of the fragment manager to {@code newState}. If the fragment manager
* changes state or {@code always} is {@code true}, any fragments within it have their
* states updated as well.
*
* @param newState The new state for the fragment manager
* @param always If {@code true}, all fragments update their state, even
* if {@code newState} matches the current fragment manager's state.
*/
void moveToState(int newState, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
if (!always && newState == mCurState) {
return;
}
mCurState = newState;
if (mActive != null) {
// Must add them in the proper order. mActive fragments may be out of order
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.
final int numActive = mActive.size();
for (int i = 0; i < numActive; i++) {
Fragment f = mActive.valueAt(i);
if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
moveFragmentToExpectedState(f);
}
}
startPendingDeferredFragments();
if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
mHost.onSupportInvalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
}
}
/**
* Moves a fragment to its expected final state or the fragment manager's state, depending
* on whether the fragment manager's state is raised properly.
*
* @param f The fragment to change.
*/
void moveFragmentToExpectedState(Fragment f) {
if (f == null) {
return;
}
int nextState = mCurState;
if (f.mRemoving) {
if (f.isInBackStack()) {
nextState = Math.min(nextState, Fragment.CREATED);
} else {
nextState = Math.min(nextState, Fragment.INITIALIZING);
}
}
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);
}
}
if (f.mIsNewlyAdded && f.mContainer != null) {
// Make it visible and run the animations
if (f.mPostponedAlpha > 0f) {
f.mView.setAlpha(f.mPostponedAlpha);
}
f.mPostponedAlpha = 0f;
f.mIsNewlyAdded = false;
// run animations:
AnimationOrAnimator anim = loadAnimation(f, f.getNextTransition(), true,
f.getNextTransitionStyle());
if (anim != null) {
setHWLayerAnimListenerIfAlpha(f.mView, anim);
if (anim.animation != null) {
f.mView.startAnimation(anim.animation);
} else {
anim.animator.setTarget(f.mView);
anim.animator.start();
}
}
}
}
if (f.mHiddenChanged) {
completeShowHideFragment(f);
}
}
调用链与上一篇文章一致,这里关注调用moveToState时的参数,其中newState为Fragment.STOPPED(3),always为false;将newState保存到mCurState中,然后调用moveFragmentToExpectedState进行fragment的状态转移,该方法最后调用5个参数的moveToState,代码如下:
@SuppressWarnings("ReferenceEquality")
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.mRemoving && newState > f.mState) {
if (f.mState == Fragment.INITIALIZING && f.isInBackStack()) {
// Allow the fragment to be created so that it can be saved later.
newState = Fragment.CREATED;
} else {
// While removing a fragment, we can't change it to a higher state.
newState = f.mState;
}
}
// Defer start if requested; don't allow it to move to STARTED or higher
// if it's not already started.
if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
newState = Fragment.STOPPED;
}
if (f.mState <= newState) {
// For fragments that are created from a layout, when restoring from
// state we don't want to allow them to be created until they are
// being reloaded from the layout.
//该分支表示生命周期转换 create -> start -> resume
} else if (f.mState > newState) {
//该分支表示生命周期转换 pause -> stop -> destoryView -> destory -> detach
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
f.performPause();
dispatchOnFragmentPaused(f, false);
}
// fall through
case Fragment.STARTED://走到这里
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.performStop();
dispatchOnFragmentStopped(f, false);
}
// fall through
case Fragment.STOPPED:
if (newState < Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
f.performReallyStop();
}
// fall through
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
if (f.mView != null) {
// Need to save the current view state if not
// done already.
if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
saveFragmentViewState(f);
}
}
f.performDestroyView();
dispatchOnFragmentViewDestroyed(f, false);
if (f.mView != null && f.mContainer != null) {
// Stop any current animations:
f.mContainer.endViewTransition(f.mView);
f.mView.clearAnimation();
AnimationOrAnimator anim = null;
if (mCurState > Fragment.INITIALIZING && !mDestroyed
&& f.mView.getVisibility() == View.VISIBLE
&& f.mPostponedAlpha >= 0) {
anim = loadAnimation(f, transit, false,
transitionStyle);
}
f.mPostponedAlpha = 0;
if (anim != null) {
animateRemoveFragment(f, anim, newState);
}
f.mContainer.removeView(f.mView);
}
f.mContainer = null;
f.mView = null;
f.mInnerView = null;
f.mInLayout = false;
}
// fall through
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
if (mDestroyed) {
// The fragment's containing activity is
// being destroyed, but this fragment is
// currently animating away. Stop the
// animation right now -- it is not needed,
// and we can't wait any more on destroying
// the fragment.
if (f.getAnimatingAway() != null) {
View v = f.getAnimatingAway();
f.setAnimatingAway(null);
v.clearAnimation();
} else if (f.getAnimator() != null) {
Animator animator = f.getAnimator();
f.setAnimator(null);
animator.cancel();
}
}
if (f.getAnimatingAway() != null || f.getAnimator() != null) {
// We are waiting for the fragment's view to finish
// animating away. Just make a note of the state
// the fragment now should move to once the animation
// is done.
f.setStateAfterAnimating(newState);
newState = Fragment.CREATED;
} else {
if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
if (!f.mRetaining) {
f.performDestroy();
dispatchOnFragmentDestroyed(f, false);
} else {
f.mState = Fragment.INITIALIZING;
}
f.performDetach();
dispatchOnFragmentDetached(f, false);
if (!keepActive) {
if (!f.mRetaining) {
makeInactive(f);
} else {
f.mHost = null;
f.mParentFragment = null;
f.mFragmentManager = null;
}
}
}
}
}
}
if (f.mState != newState) {
Log.w(TAG, "moveToState: Fragment state for " + f + " not updated inline; "
+ "expected state " + newState + " found " + f.mState);
f.mState = newState;
}
}
这里注意,Fragment执行完onPause之后,mState为STARTED(4),而newState为STOPPED(3),所以进入销毁流程的Fragment.STARTED分支,即执行如下代码:
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.performStop();
dispatchOnFragmentStopped(f, false);
}
newState < Fragment.STARTED条件为真,因此进入代码块中,performStop代码如下:
void performStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchStop();
}
mState = STOPPED;
mCalled = false;
onStop();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onStop()");
}
}
处理LifecycleRegistry中的回调,处理子fragmet的生命周期回调分发,改变当前fragment状态(mState = STOPPED),调用当前fragment的生命周期方法onStop。回到上一步,继续调用方法dispatchOnFragmentStopped,代码如下:
void dispatchOnFragmentStopped(Fragment f, boolean onlyRecursive) {
if (mParent != null) {
FragmentManager parentManager = mParent.getFragmentManager();
if (parentManager instanceof FragmentManagerImpl) {
((FragmentManagerImpl) parentManager)
.dispatchOnFragmentStopped(f, true);
}
}
for (Pair p : mLifecycleCallbacks) {
if (!onlyRecursive || p.second) {
p.first.onFragmentStopped(this, f);
}
}
}
处理父fragment生命周期分发,处理mLifecycleCallbacks的注册回调。
onStop分支总结:
1 处理mLifecycleRegistry中的回调。
2 通过mChildFragmentManager.dispatchPause()分发其子fragment的生命周期回调。
3 调用onStop执行自己的生命周期方法(同时mState = STOPPED)。
4 如果有父framnet,则分发父frament的生命周期回调。
5 执行保存在mLifecycleCallbacks中的生命周期回调(比如LeakCanary的内存泄漏判断就是此时触发的)。
执行完onStop之后,上面的逻辑将穿透到Fragment.STOPPED分支,代码如下:
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.performStop();
dispatchOnFragmentStopped(f, false);
}
// fall through
case Fragment.STOPPED://走到这里
if (newState < Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
f.performReallyStop();
}
然而由于此时newState=Fragment.STOPPED,因此将会穿透其余的分支最后跳出整个大switch代码块。
还记得开篇说的MSG_REALLY_STOPPED消息吗,其对应的代码逻辑如下:
final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REALLY_STOPPED:
if (mStopped) {
doReallyStop(false);
}
break;
case MSG_RESUME_PENDING:
onResumeFragments();
mFragments.execPendingActions();
break;
default:
super.handleMessage(msg);
}
}
};
void doReallyStop(boolean retaining) {
if (!mReallyStopped) {
mReallyStopped = true;
mRetaining = retaining;
mHandler.removeMessages(MSG_REALLY_STOPPED);
onReallyStop();
}
}
/**
* Pre-HC, we didn't have a way to determine whether an activity was
* being stopped for a config change or not until we saw
* onRetainNonConfigurationInstance() called after onStop(). However
* we need to know this, to know whether to retain fragments. This will
* tell us what we need to know.
*/
void onReallyStop() {
mFragments.dispatchReallyStop();
}
最后调用dispatchReallyStop方法,该方法也会进入5个参数的moveToState方法中,相应分支代码如下:
case Fragment.STOPPED:
if (newState < Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
f.performReallyStop();
}
继续调用performReallyStop方法,如下:
void performReallyStop() {
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchReallyStop();
}
mState = ACTIVITY_CREATED;
}
首先是分发事件,然后是改变fragment的状态,此时fragment的mState 为 ACTIVITY_CREATED。
到这里,onStop执行完成。
此时,Fragment的mState为ACTIVITY_CREATED。