从源码来看Fragment的生命周期(二)

来源:互联网 发布:java基本命名规范 编辑:程序博客网 时间:2024/06/07 23:08

7、moveToState

上一盘说Fragment的生命周期说到了moveToState这个方法,这篇我们继续:

首先看moveToState这个方法的定义:

void moveToState(Fragment f, int newState, int transit, int transitionStyle,boolean keepActive)
static final int INVALID_STATE = -1;   // Invalid state used as a null value.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.

在moveToState方法一开始,会对传入的newState进行校准,具体方式如下:

//如果传入的newState大于Fragment.CREATED,那么在两种情况下将他强行设置为Fragment.CREATED//1、这个fragment已经被移除了,即调用removeFragment方法//2、这个fragment已经没有附着在当前activity上了,即调用了detachFragment方法if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {    newState = Fragment.CREATED;}//如果fragment已经被remove掉了,那么如果传入的newState大于原始的mState时,是不能增加mState的值的if (f.mRemoving && newState > f.mState) {    // While removing a fragment, we can't change it to a higher state.    newState = f.mState;}//如果fragment要求延时start,并且fragment的原状态小于STARTED,而传入的状态大于STOPPED(最少为STARTED),那么强行将状态置为STOPPEDif (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {    newState = Fragment.STOPPED;}

校准完毕之后,就开始同步状态,同步状态有两种情况,一种是传入的newState大于原有的mState,这时状态会上升,另外一种是小于,这时状态会下降。
在状态上升中,是通过switch-case进行不同分支跳转的,但是在这个case的最后并没有使用break语句跳出分支,这时因为在执行完前一个状态的逻辑后,还需要继续往后执行,所有它其中的case分支都是按照INITIALIZING、CREATED、ACTIVITY_CREATED、STOPPED、STARTED、RESUMED顺序排布的,因为代码较长,所以这里都以注释的形式进行说明。

INITIALIZING:

//首先会判断mSavedFragmentState是否为null,这个是用来保存状态恢复而使用的,和Activity非正常销毁时保存状态类似if (f.mSavedFragmentState != null) {    ......}//配置fragment的参数......//验证一些信息f.mCalled = false;f.onAttach(mActivity);if (!f.mCalled) {    throw new SuperNotCalledException("Fragment " + f                                      + " did not call through to super.onAttach()");}if (f.mParentFragment == null) {    mActivity.onAttachFragment(f);}//执行fragment的生命周期if (!f.mRetaining) {    //在这里会调用fragment的performCreate方法,在performCreate方法中会调用生命周期的onCreate方法    f.performCreate(f.mSavedFragmentState);}f.mRetaining = false;//如果这个fragment是layout中的,那么还执行另外的一些生命周期if (f.mFromLayout) {    //performCreateView方法中会调用onCreateView方法    f.mView = f.performCreateView(f.getLayoutInflater(                                      f.mSavedFragmentState), null, f.mSavedFragmentState);    //如果从onCreateView获得的View不为null,那么还会调用onViewCreated方法    if (f.mView != null) {        f.mView.setSaveFromParentEnabled(false);        if (f.mHidden) f.mView.setVisibility(View.GONE);        f.onViewCreated(f.mView, f.mSavedFragmentState);    }}

CREATED:

//因为上面的一个case没有break,所以从第二个case开始,都会先判断newState,才能决定是否继续执行当前state的逻辑if (newState > Fragment.CREATED) {    if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);    //如果fragment不是layout中的,那么就会执行fragment的生命周期(和INITIALIZING中类似)    //不过这里还添加了一个新的逻辑,那就是拿到fragment需要填充的view的id,在fragment的view构建完毕之后,    //通过container.addView(f.mView),将fragment添加到需要填充的view中,    if (!f.mFromLayout) {        ViewGroup container = null;        if (f.mContainerId != 0) {            container = (ViewGroup)mContainer.onFindViewById(f.mContainerId);            if (container == null && !f.mRestored) {                throwException(new IllegalArgumentException(                                   "No view found for id 0x"                                   + Integer.toHexString(f.mContainerId) + " ("                                   + f.getResources().getResourceName(f.mContainerId)                                   + ") for fragment " + f));            }        }        f.mContainer = container;        f.mView = f.performCreateView(f.getLayoutInflater(                                          f.mSavedFragmentState), container, f.mSavedFragmentState);        if (f.mView != null) {            f.mView.setSaveFromParentEnabled(false);            if (container != null) {                Animator anim = loadAnimator(f, transit, true,                                             transitionStyle);                if (anim != null) {                    anim.setTarget(f.mView);                    setHWLayerAnimListenerIfAlpha(f.mView, anim);                    anim.start();                }                container.addView(f.mView);            }            if (f.mHidden) f.mView.setVisibility(View.GONE);            f.onViewCreated(f.mView, f.mSavedFragmentState);        }    }    //执行完生命周期之后,调用ChildFragment中的performActivityCreated方法,这样最终会调用到ChildFragment中的moveToState方法    f.performActivityCreated(f.mSavedFragmentState);    if (f.mView != null) {        f.restoreViewState(f.mSavedFragmentState);    }    f.mSavedFragmentState = null;}

ACTIVITY_CREATED:
STOPPED:

if (newState > Fragment.STOPPED) {    if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);    //如果newState大于STOPPED(至少是STARTED),那么调用fragment的生命周期onStart方法    f.performStart();}

STARTED:

if (newState > Fragment.STARTED) {    if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);    f.mResumed = true;    //调用fragment的生命周期onResume    f.performResume();    f.mSavedFragmentState = null;    f.mSavedViewState = null;}

到这里,提升状态的逻辑基本就说完了,理解完提升状态的逻辑,那么降低状态的逻辑也就大同小异了,这里就放一起说了:

降低状态:

case Fragment.RESUMED:if (newState < Fragment.RESUMED) {    if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);    //如果小于RESUMED,那么调用生命周期onPause    f.performPause();    f.mResumed = false;}case Fragment.STARTED:if (newState < Fragment.STARTED) {    if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);    //如果小于STARTED,那么调用生命周期onStop    f.performStop();}case Fragment.STOPPED:case Fragment.ACTIVITY_CREATED:if (newState < Fragment.ACTIVITY_CREATED) {    if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);    //如果mView不为null,清除之前保存的一些状态    if (f.mView != null) {        if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {            saveFragmentViewState(f);        }    }    //调用onDestroyView生命周期方法    f.performDestroyView();    //如果有退出动画,那么播放退出动画    if (f.mView != null && f.mContainer != null) {        Animator anim = null;        if (mCurState > Fragment.INITIALIZING && !mDestroyed) {            anim = loadAnimator(f, transit, false,                                transitionStyle);        }        if (anim != null) {            final ViewGroup container = f.mContainer;            final View view = f.mView;            final Fragment fragment = f;            container.startViewTransition(view);            f.mAnimatingAway = anim;            f.mStateAfterAnimating = newState;            anim.addListener(new AnimatorListenerAdapter() {                @Override                public void onAnimationEnd(Animator anim) {                    container.endViewTransition(view);                    if (fragment.mAnimatingAway != null) {                        fragment.mAnimatingAway = null;                        moveToState(fragment, fragment.mStateAfterAnimating,                                    0, 0, false);                    }                }            });            anim.setTarget(f.mView);            setHWLayerAnimListenerIfAlpha(f.mView, anim);            anim.start();        }        //将fragment的view从界面移除        f.mContainer.removeView(f.mView);    }    f.mContainer = null;    f.mView = null;}case Fragment.CREATED:if (newState < Fragment.CREATED) {    if (mDestroyed) {        //如果fragment的Activity销毁,那么停止fragment的动画,并将mAnimatingAway设置为null        if (f.mAnimatingAway != null) {            Animator anim = f.mAnimatingAway;            f.mAnimatingAway = null;            anim.cancel();        }    }    if (f.mAnimatingAway != null) {        //如果mAnimatingAway没有设置为null,那么状态不变        f.mStateAfterAnimating = newState;        newState = Fragment.CREATED;    } else {        //如果mAnimatingAway状态为null        if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);        if (!f.mRetaining) {            //调用fragment的生命周期onDestroy            f.performDestroy();        }        f.mCalled = false;        //调用fragment的生命周期onDetach        f.onDetach();        if (!f.mCalled) {            throw new SuperNotCalledException("Fragment " + f                                              + " did not call through to super.onDetach()");        }        if (!keepActive) {            if (!f.mRetaining) {                //回收fragment的index                makeInactive(f);            } else {                f.mHost = null;                f.mParentFragment = null;                f.mFragmentManager = null;                f.mChildFragmentManager = null;            }        }    }}

总结

①到这里,Fragment的源码也算是基本完结了,相比于Activity,Fragment更像一个java类,它没有Activity那样实现很多的视图接口,也没有实现任何的键盘监听,从这里我们就可以确定fragment里的键盘事件应该是通过Activity传入的。
②在我们使用Fragment的时候,通过getFragmentManager方法拿到的其实是FragmentManagerImpl,他是FragmentManagerI的子类。而Fragment的生命周期,也是通过它进行控制的。
③在我们通过beginTransaction,add方法添加Fragment的时候,只是把Fragment和操作类型保存到一个BackStackRecord的Op对象中去了,虽然Fragment对象是通过我们new Fragment创建出来的,但是此时的Fragment并没有执行它生命周期的onCreate方法,这点和Activity是不同的,Activity是会在系统创建它之后,立刻执行它出onCreate方法。
④对Fragment状态的的变更,是在我们调用完commit方法后才开始的,他会通过mHandler.post(mExecCommit),最后调用到execPendingActions方法中。
⑤在execPendingActions方法中,会拿到之前在BackStackRecord对象,而BackStackRecord是实现了Runnable接口是,所以会执行BackStackRecord中的run方法。
⑥在BackStackRecord 的run中,会针对不同的操作类型,比如add,remove调用FragmentManagerImpl中不同的方法,例如addFragment,removeFragment,在这些方法中,首先会更改fragment对象中对应的配置参数,然后会将fragment传入调用moveToState方法。
⑦在FragmentManagerImpl的moveToState方法中,会调用Fragment的生命周期方法。

上述,就是Fragment源码中,对于Fragment生命周期的调用了,当然还是那句话,Android的源码远比我看的复杂,而我当前也只是通过一个简单的例子来看Fragment的生命周期,自然不可能面面俱到,至于其中的细节部分,还是需要以后慢慢研究咯。

0 0
原创粉丝点击