Fragment生命周期源码分析
Posted 白嫩豆腐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Fragment生命周期源码分析相关的知识,希望对你有一定的参考价值。
前言
上一篇介绍了Fragment的新建过程,这一篇我们介绍一下Fragment的生命周期源码的过程,这里我们假设的情景是fragment已经添加到页面上了,通过上一篇我们知道Fragment其实就是activity的一个成员变量,用来提供一个view,所以Fragment的生命周期肯定是activity控制的(其实activitymanageservice也可以控制,但是完全没必要那么复杂),所以我们就直接看activity源码即可,可是我们忽然发现androidx.fragment.app.Fragment其实是一个第三方库,那么我们的系统一般没必要引用第三方库,我们会发现系统其实有一个叫android.app.Fragment。所以说控制Fragment生命周期的肯定是第三方库。我们只要跟进第三方库即可
正文
前言说了一大堆东东,其实就可以得到一个结论
我们用的androidx.fragment.app.Fragment声明周期的控制是FragmentActivity
那我们直接看FragmentActivity
源码,简短版大概是这样:
public class FragmentActivity extends ComponentActivity
protected void onCreate(@Nullable Bundle savedInstanceState)
//恢复数据
if (savedInstanceState != null)
......
mFragments.dispatchCreate();
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs)
final View v = dispatchFragmentsOnCreateView(parent, name, context, attrs);
@Override
public View onCreateView(String name, Context context, AttributeSet attrs)
final View v = dispatchFragmentsOnCreateView(null, name, context, attrs);
final View dispatchFragmentsOnCreateView(View parent, String name, Context context,
AttributeSet attrs)
return mFragments.onCreateView(parent, name, context, attrs);
@Override
protected void onDestroy()
super.onDestroy();
mFragments.dispatchDestroy();
@Override
protected void onPause()
super.onPause();
mResumed = false;
if (mHandler.hasMessages(MSG_RESUME_PENDING))
mHandler.removeMessages(MSG_RESUME_PENDING);
onResumeFragments();
mFragments.dispatchPause();
@Override
protected void onResume()
super.onResume();
mHandler.sendEmptyMessage(MSG_RESUME_PENDING);
mResumed = true;
mFragments.execPendingActions();
@Override
protected void onPostResume()
super.onPostResume();
mHandler.removeMessages(MSG_RESUME_PENDING);
onResumeFragments();
mFragments.execPendingActions();
protected void onResumeFragments()
mFragments.dispatchResume();
@Override
protected void onStart()
super.onStart();
mStopped = false;
if (!mCreated)
mCreated = true;
mFragments.dispatchActivityCreated();
mFragments.noteStateNotSaved();
mFragments.execPendingActions();
mFragments.dispatchStart();
@Override
protected void onStop()
markFragmentsCreated();
mFragments.dispatchStop();
emmm 看完以后忽然觉得这个代码好整齐呀,如果结合上一篇博客,会有种豁然开朗的感觉,他不就是把自己的状态告诉Fragment,然后就完事了,不过我们稍微留意一下,有些生命周期为了代码健壮性,搞了一些奇怪的代码,但是我们很简单的理解,就按照activity的生命周期来分析一下Fragment到底是如何工作的。
我们从oncreat()开始
public void dispatchCreate()
mStateSaved = false;
mStopped = false;
dispatchStateChange(Fragment.CREATED);
private void dispatchStateChange(int nextState)
try
mExecutingActions = true;
moveToState(nextState, false);
finally
mExecutingActions = false;
execPendingActions();
熟悉之前代码的,就会对现在这个代码很熟悉了,execPendingActions这个函数其实就是加入Fragment或者用来暂时加入栈操作的,这个因为对我们的Fragment状态是毫无影响的,所以很容易推断,他就是在 moveToState(nextState, false)中操作的,我们进去看看吧:
void moveToState(int newState, boolean always)
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();
......
看下注释,第一个是循环中,就让Fragment处于正常状态,我们刚才已经改变了Fragment的状态,很容易理解就是这里来处理的,
第二个是处理remove和detach的,我们只要跟踪moveFragmentToExpectedState就ok了。
void moveFragmentToExpectedState(Fragment f)
......
moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
//Fragment添加是有顺序的,这里每次改变后,都把Fragment给调到最高层,主要是为了适应刚才的那个循环,肯定是后加入的,最后会显示在屏幕上
//还有的是为了动画,
oid moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive)
switch (f.mState)
case Fragment.CREATED:
// This is outside the if statement below on purpose; we want this to run
// even if we do a moveToState from CREATED => *, CREATED => CREATED, and
// * => CREATED as part of the case fallthrough above.
ensureInflatedFragmentView(f);
if (newState > Fragment.CREATED)
if (!f.mFromLayout)
ViewGroup container = null;
if (f.mContainerId != 0)
......
container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
......
f.mContainer = container;
//调用oncreatView
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
f.mInnerView = f.mView;
container.addView(f.mView);
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;
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);
f.performStart();
dispatchOnFragmentStarted(f, false);
// fall through
case Fragment.STARTED:
if (newState > Fragment.STARTED)
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
f.performResume();
dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
函数大概就这样,很容易看到当activity声明周期到了oncreat时候,Fragment走过了三个生命周期。但是我们在第一个周期中
最后发现这里的给分析都是错的,因为mHost.getHandler().post(mExecCommit);
一直要到activity的onresume中才会执行,我们代码分析完全都是错的。其实所有的声明周期相关的都是在
@Override
protected void onStart()
super.onStart();
mStopped = false;
if (!mCreated)
mCreated = true;
mFragments.dispatchActivityCreated();
mFragments.noteStateNotSaved();
mFragments.execPendingActions();
mFragments.dispatchStart();
中执行的,代码和上面流程一样,只是吧改变声明周期的代码放入到直接的函数调用中了。有机会在重新分析一下Android的 消息分发流程。这里就暂时不在详细追究了。
后记
因为中间好多交叉知识点。我还以为是activity的声明周期影响的呢,最后发现仅仅是Android消息机制的影响,以后可以再分析一下Android的消息通讯机制。这里就暂时到这里,其实这个东西也没什么好过多详细介绍的
以上是关于Fragment生命周期源码分析的主要内容,如果未能解决你的问题,请参考以下文章