承接上一篇文章Fragment.onStop的事情,继续研究Fragment.onDestroy干了什么,Activity中的代码入口如下:
//FragmentActivity.java
@Override
protected void onDestroy() {
super.onDestroy();
doReallyStop(false);
if (mViewModelStore != null && !mRetaining) {
mViewModelStore.clear();
}
mFragments.dispatchDestroy();
}
//FragmentController.java
/**
* Moves all Fragments managed by the controller's FragmentManager
* into the destroy state.
* Call when Fragments should be destroyed.
*
* @see Fragment#onDestroy()
*/
public void dispatchDestroy() {
mHost.mFragmentManager.dispatchDestroy();
}
//FragmentManager.java
public void dispatchDestroy() {
mDestroyed = true;
execPendingActions();
dispatchStateChange(Fragment.INITIALIZING);
mHost = null;
mContainer = null;
mParent = null;
}
注意最后的dispatchDestroy中给dispatchStateChange传递的nextState参数为Fragment.INITIALIZING,中间的代码链跳转与前面两篇文章分析的一致,这里跳过了;直接定位到状态转移函数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;
}
}
由前面一篇文章我们知道,onStop完成之后相应fragment的状态为Fragment.ACTIVITY_CREATED,因此这里将会进入Fragment.ACTIVITY_CREATED对应的fragment销毁流程分支,这里单独拿出来分析如下:
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
首先是fragment相关状态的保存,然后调用performDestroyView执行销毁相关的回调,调用dispatchOnFragmentViewDestroyed执行销毁分发回调,最后是fragment相关view的移除及状态置位。这里重点看performDestroyView,代码如下:
void performDestroyView() {
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchDestroyView();
}
mState = CREATED;
mCalled = false;
onDestroyView();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onDestroyView()");
}
if (mLoaderManager != null) {
// Handles the detach/reattach case where the view hierarchy
// is destroyed and recreated and an additional call to
// onLoadFinished may be needed to ensure the new view
// hierarchy is populated from data from the Loaders
mLoaderManager.markForRedelivery();
}
mPerformedCreateView = false;
}
首先是子fragment的生命周期分发,然后是 mState = CREATED(1),onDestroyView生命周期回调。
函数返回到Fragment.ACTIVITY_CREATED分支中,此时执行流程将穿透到下一个分支中,代码如下:
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;
}
}
}
}
注意到此时由于newState为INITIALIZING(0),因此条件newState < Fragment.CREATED得以满足,这里就要继续最后的销毁流程了(不再透明穿透,执行完在跳出大switch块)。
首先判断mDestroyed状态,如果为true则表示相应的宿主activity已经销毁,这里需要停止fragment相应的状态(因为已经不需要了);条件f.getAnimatingAway() != null || f.getAnimator() != null判断当前是不是在执行fragment关闭动画,我们这里假定没执行;因此进入另外一个分支f.mRetaining为false,调用performDestroy销毁fragment,调用dispatchOnFragmentDestroyed分发生命周期事件,调用f.performDetach()与宿主activity分离,调用dispatchOnFragmentDetached(f, false)分发detach生命周期事件。这里关注performDestroy以及performDetach两个方法,首先看performDestroy,代码如下:
void performDestroy() {
//生命周期事件分发
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
if (mChildFragmentManager != null) {
mChildFragmentManager.dispatchDestroy();
}
//改变状态到初始状态
mState = INITIALIZING;
mCalled = false;
mIsCreated = false;
//回调生命周期函数
onDestroy();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onDestroy()");
}
//清空FragmentManager
mChildFragmentManager = null;
}
嗯,已经注释,不再说明。再看performDetach,如下:
void performDetach() {
mCalled = false;
onDetach();
mLayoutInflater = null;
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onDetach()");
}
// Destroy the child FragmentManager if we still have it here.
// We won't unless we're retaining our instance and if we do,
// our child FragmentManager instance state will have already been saved.
if (mChildFragmentManager != null) {
if (!mRetaining) {
throw new IllegalStateException("Child FragmentManager of " + this + " was not "
+ " destroyed and this fragment is not retaining instance");
}
mChildFragmentManager.dispatchDestroy();
mChildFragmentManager = null;
}
}
没啥特别的,也就是回调onDetach,相关状态置位。
好了,Fragment已经销毁,一切归零,最后 mState = INITIALIZING,又回到了初始的地方。