Android Gems — Fragment本质之生命周期管理

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/threepigs/article/details/53453252

Fragment最早引入是在给平板的Android 3.0系统,用来解决Pad上UI的模块化。随后逐渐推广到Phone UI上,3.0之前的版本则通过Support包引入。Fragment本质上是带生命周期管理的View的Wrapper,解耦了Activity和View,一方面Activity可以不用再处理View的逻辑;另一方面View也可以只专注渲染,不用关心Controller逻辑。Fragment就是他们之间的桥梁,使得UI模块可以方便的被各个Activity复用。
Fragment对开发者已经不再陌生,本文也并不打算介绍Fragment的api使用,而是分析Fragment的源码,从源码的角度来对Fragment的使用有更深刻的理解。
Fragment相关的源码存放在framework/base/core/java/android/app/下,有如下几个重要的类:
一,Fragment
Fragment基本类,生命周期如下:

    void onAttach(Context context)
    void onCreate(Bundle savedInstanceState)
    View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    void onActivityCreated(Bundle savedInstanceState)
    void onStart()
    void onStop()
    void onResume()
    void onPause()
    void onDestroyView()
    void onDestroy()
    void onDetach()
Fragment的生命周期和Activity是对应的。
二,FragmentManager
FragmentManager是Fragment生命周期管理的核心类,确切的说,他是个抽象类,具体的实现是FragmentManagerImpl,所有的Fragment的管理:添加、删除、显示、隐藏等都由FragmentManagerImpl完成。
三,FragmentController
Activity拥有FragmentController的实例,通过FragmentController来分发Activity的生命周期事件,而FragmentController只是给外部的FragmentManager接口的wrapper,实际的实现还是由FragmentManager来完成。
四,FragmentTransaction
FragmentTransaction是一组Fragment操作集合,由FragmentManager调用beginTransaction来获得一个FragmentTransaction,之后可以执行add/replace/remove等Fragment操作,在调用Transaction的commit之前,这些操作还并未生效。FragmentTransaction之所以被称为事务,是因为它执行的Fragment Op集合是可以回退的,后面我们做源码分析的时候会详细分析。FragmentTransaction是个抽象类,实现类是BackStackRecord。
Fragment本质系列文章将从如下几个角度,有针对性的对Fragment进行源码分析,分析Fragment本质,从而达到深入浅出的目的。
一,Fragment的生命周期管理
二,Fragment的View管理
三,FragmentTransaction的事务和BackStack管理
四,Fragment的状态保存和恢复
本文先分析Fragment的生命周期管理:
Fragment有如下几种状态和其生命周期对应,状态包括:
    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.
FragmentManager的mCurState状态是Activity的生命周期是保持一致的,而每个Fragment里有mState字段表示自己单独的状态,会通过moveToState来和FragmentManager的mCurState状态保持同步。为什么这样设计呢?原因是Fragment是可以动态add的,添加的时候,Activity的可以在任何的阶段,而FragmentManager是静态的,从Activity创建的时候就存在,因此就用FragmentManager来和Activity保持同步,而Fragment add之后将会和其同步状态。下面的这些dispatch函数定义在FragmentManager里,Activity在其生命周期里通过FragmentController调用这些方法,完成Activity和FragmentManager之间的状态同步:
    public void dispatchCreate() {
        mStateSaved = false;
        moveToState(Fragment.CREATED, false);
    }    
    public void dispatchActivityCreated() {
        mStateSaved = false;
        moveToState(Fragment.ACTIVITY_CREATED, false);
    }    
    public void dispatchStart() {
        mStateSaved = false;
        moveToState(Fragment.STARTED, false);
    }    
    public void dispatchResume() {
        mStateSaved = false;
        moveToState(Fragment.RESUMED, false);
    }    
    public void dispatchPause() {
        moveToState(Fragment.STARTED, false);
    }    
    public void dispatchStop() {
        moveToState(Fragment.STOPPED, false);
    }    
    public void dispatchDestroy() {
        mDestroyed = true;
        execPendingActions();
        moveToState(Fragment.INITIALIZING, false);
        mHost = null;
        mContainer = null;
        mParent = null;
    }
Activity的onCreate调用dispatchCreate,dispatchActivityCreated方法,这时候FragmentManager的状态就切换成ACTIVITY_CREATED,Activity的onStart执行dispatchStart把状态切换成STARTED,onResume切换成RESUMED状态,onPause切换STARTED,onStop切换成STOPPED,onDestroy就切换到了最初的INITIALIZING。这样FragmentManager就保证了和Activity的生命周期保持一致。
FragmentManager的状态是静态的还比较简单,接下来就得分析Fragment的状态切换了。Fragment刚new出来时的初始状态mState是INITIALIZING,状态切换是由FragmentManager的moveToState函数完成。Fragment状态切换是和Fragment的几个操作分不开的,我们先对Fragment的基本操作进行分析,再对moveToState方法做分析。
我们总结一下FragmentTransaction的几个基本操作:
1, add
FragmentTransaction的事务实现细节,我们放到后面的章节介绍,只需知道add的操作最后调用FragmentManager的addFragment方法来增加Fragment
    public void addFragment(Fragment fragment, boolean moveToStateNow) {
        if (mAdded == null) {
            mAdded = new ArrayList<Fragment>();
        }
        if (DEBUG) Log.v(TAG, "add: " + fragment);
        makeActive(fragment);    // 将Fragment加入mActive
        if (!fragment.mDetached) {   // 忽略已经detach的Fragment
            if (mAdded.contains(fragment)) {
                throw new IllegalStateException("Fragment already added: " + fragment);
            }
            mAdded.add(fragment);  // 加如mAdded数组
            fragment.mAdded = true;
            fragment.mRemoving = false;
            if (fragment.mHasMenu && fragment.mMenuVisible) {
                mNeedMenuInvalidate = true;
            }
            if (moveToStateNow) {
                moveToState(fragment);
            }
        }
    }
首先makeActive来激活Fragment,而激活Fragment要做的事就是把Fragment插入到mActive数组里,mActive是FragmentManager的一个字段,用来保存active的Fragment列表。makeActive只有addFragment才会调用,所以其本质是add过的Fragment。mActive设计的目的主要是为了保存和恢复状态,保存所有mActive的所有Fragment,当进程被杀后恢复的时候,可以恢复出之前的所有Fragment,再接着对之前的BackStack的所有FragmentTransaction事务做redo,从而恢复进程被杀之前的状态 。由于Fragment的恢复是基于BackStack的,所以一个Fragment是否是Active的依据是其是否在BackStack里,也就是mBackStackNesting大于0,Active的Fragment在removeFragment的时候,只会将其从mAdded列表里删除,而不会从mActive删除,因为在做状态恢复的时候会要用这个Fragment,这也就是mActive和mAdded的区别,两者是不能等价的。如果Fragment不是active了,removeFragment就会调用makeInactive移除Fragment,另外Activity的onDestroy调用FragmentManager的dispatchDestroy时也会makeInactive把Fragment从mActive里删除(后续分析moveToState的时候会看到)。下面我们看看makeActive和makeInactive的定义加深一下印象。
    void makeActive(Fragment f) 
        if(f.mIndex >= 0) {   // 表示Fragment已经是active的了
            return;
        }        
        if (mAvailIndices == null || mAvailIndices.size() <= 0) {
            if (mActive == null) {
                mActive = new ArrayList<Fragment>();
            }
            // 将Fragment加到mActive
            f.setIndex(mActive.size(), mParent);
            mActive.add(f);            
        } else {
            // 复用mActive的索引,将Fragment加到mActive
            f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1), mParent);
            mActive.set(f.mIndex, f);
        }
    }    
    void makeInactive(Fragment f) {
        if (f.mIndex < 0) {  // 已经是inactive的了
            return;
        }
        // 将Fragment从mActive移除
        mActive.set(f.mIndex, null);
        if (mAvailIndices == null) {
            mAvailIndices = new ArrayList<Integer>();
        }
        mAvailIndices.add(f.mIndex);        // 回收index
        mHost.inactivateFragment(f.mWho);
        f.initState();   // 重置Fragment的状态
    }
再回到addFragment,Fragment被makeActive之后就加入mAdded列表,最后根据moveToStateNow的值决定是否马上做状态切换moveToState(从源码上分析,只有从layout里的Fragment被onCreateView创建的时候,调用moveToState方法时才会将moveToStateNow置true,其他的时候比如FragmentTransaction执行事务时,会在所有op执行完之后,统一moveToStateNow),moveToSave会将Fragment的状态和FragmentManager的状态同步,同步的时候就会调用Fragment的生命周期函数,具体的分析我们留到分析moveToSave函数的时候。
2,replace
replace是FragmentTransaction的接口,FragmentManager没有与其对应的方法,这是FragmentTransaction内部的操作。replace的两参数的方法replace(int containerViewId, Fragment fragment),表示要替换containerViewId下所有的Fragment。所谓的替换操作,就是把containerId等于containerViewId的所有Fragment都removeFragment。然后将第二个参数fragment调用addFragment加入。三参数的方法replace(int containerViewId, Fragment fragment, String tag)和两参数的差不多,设置替换后的Fragment的tag,可用户后续通过tag从FragmentManager里查找到Fragment。
    public FragmentTransaction replace(int containerViewId, Fragment fragment) {
        return replace(containerViewId, fragment, null);
    }

    public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
        if (containerViewId == 0) {
            throw new IllegalArgumentException("Must use non-zero containerViewId");
        }

        doAddOp(containerViewId, fragment, tag, OP_REPLACE);
        return this;
    }
doAddOp方法是把Op加入双向链表的表尾(mHead是表头,mTail是表尾),FragmentTransaction的是个事务,意味着可以回退,只要调用了addToBackStack方法,那么每次执行完Op之后就会调用FragmentManager的addBackStackState方法,把自己加到BackStack里,这样按back键后,就会一层一层的undo,而undo的实现就在FragmentTransaction的popFromBackStack里,详细实现我们放到后面的FragmentTransaction的BackStack管理里分析。我们回到replace操作,其执行在run方法里,我们摘录replace部分:
                case OP_REPLACE: {
                    Fragment f = op.fragment;
                    int containerId = f.mContainerId;
                    if (mManager.mAdded != null) {
                        for (int i = 0; i < mManager.mAdded.size(); i++) {
                            Fragment old = mManager.mAdded.get(i);
                            if (old.mContainerId == containerId) {
                                if (old == f) {
                                    op.fragment = f = null;
                                } else {
                                    if (op.removed == null) {
                                        op.removed = new ArrayList<Fragment>();
                                    }
                                    op.removed.add(old);
                                    old.mNextAnim = op.exitAnim;
                                    if (mAddToBackStack) {
                                        old.mBackStackNesting += 1;
                                    }
                                    mManager.removeFragment(old, mTransition, mTransitionStyle);
                                }
                            }
                        }
                    }
                    if (f != null) {
                        f.mNextAnim = op.enterAnim;
                        mManager.addFragment(f, false);
                    }
                }
从以上代码可知,replace的语义是查找mAdded列表,将containerId对应的所有Fragment都加入removed列表,并增加其mBackStackNesting,mBackStackNesting表示Fragment在back stack里的层数,越大就越接近栈顶,接着调用removeFragment将这些Fragment移除,之后将待替换的Fragment加到FragmentManager里。在这里,mBackStackNesting++的目的在于避免removeFragment的时候将其从mActive列表删除,因为后续popFromBackStack的时候还会undo,将这些Fragment加回来,如果mActive里没有了,影响的就是进程被杀死后,状态恢复没法完全还原,这里的mBackStackNesting+1会在这个BackStackRecord被popFromBackStack的时候,调用bumpBackStackNesting(-1)给减掉。这种在mActive列表里,而不在mAdded列表里的Fragment的状态只能是CREATED,这个状态的Fragment不会将其View加到UI的ViewTree里,所以用户是不可见的。
                case OP_REPLACE: {
                    Fragment f = op.fragment;
                    if (f != null) {
                        f.mNextAnim = op.popExitAnim;
                        mManager.removeFragment(f,
                                FragmentManagerImpl.reverseTransit(mTransition),
                                mTransitionStyle);
                    }
                    if (op.removed != null) {
                        for (int i = 0; i < op.removed.size(); i++) {
                            Fragment old = op.removed.get(i);
                            old.mNextAnim = op.popEnterAnim;
                            mManager.addFragment(old, false);
                        }
                    }
                }
上面是popFromBackStack的replace的undo操作,removed列表里之前remove了的Fragment就会被重新addFragment。
3, remove
removeFragment和addFragment是成对的,我们接着分析一下removeFragment:
    public void removeFragment(Fragment fragment, int transition, int transitionStyle) {
        final boolean inactive = !fragment.isInBackStack();
        if (!fragment.mDetached || inactive) {
            if (mAdded != null) {
                mAdded.remove(fragment);
            }
            if (fragment.mHasMenu && fragment.mMenuVisible) {
                mNeedMenuInvalidate = true;
            }
            fragment.mAdded = false;	
            fragment.mRemoving = true;
            moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED,
                    transition, transitionStyle, false);
        }
    }
正如之前所说,removeFragment的时候,会看Fragment是否还在BackStack里,如果还在,那么仅仅是从mAdded列表里删除,mActive列表里的还继续保留,并将Fragment的状态置为CREATED。
4,show
showFragment比较简单,如果当前是hidden状态,就把fragment的View设置VISIBLE,并不影响Fragment的生命周期,所以不需要moveToState。
    public void showFragment(Fragment fragment, int transition, int transitionStyle) {
        if (fragment.mHidden) {
            fragment.mHidden = false;
            if (fragment.mView != null) {
                Animator anim = loadAnimator(fragment, transition, true,
                        transitionStyle);
                if (anim != null) {
                    anim.setTarget(fragment.mView);
                    setHWLayerAnimListenerIfAlpha(fragment.mView, anim);
                    anim.start();
                }
                fragment.mView.setVisibility(View.VISIBLE);
            }
            if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
                mNeedMenuInvalidate = true;
            }
            fragment.onHiddenChanged(false);
        }
    }

5,hide
hideFragment和showFragment刚好对称,将Fragment的View设成GONE。不影响生命周期,也不需要moveToState。
public void hideFragment(Fragment fragment, int transition, int transitionStyle) {
        if (!fragment.mHidden) {
            fragment.mHidden = true;
            if (fragment.mView != null) {
                Animator anim = loadAnimator(fragment, transition, false,
                        transitionStyle);
                if (anim != null) {
                    anim.setTarget(fragment.mView);
                    final Fragment finalFragment = fragment;
                    anim.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            if (finalFragment.mView != null && finalFragment.mHidden) {
                                finalFragment.mView.setVisibility(View.GONE);
                            }
                        }
                    });
                    setHWLayerAnimListenerIfAlpha(finalFragment.mView, anim);
                    anim.start();
                } else {
                    fragment.mView.setVisibility(View.GONE);
                }
            }
            if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
                mNeedMenuInvalidate = true;
            }
            fragment.onHiddenChanged(true);
        }
    }

6, attach
attachFragment将detach的Fragment重新加入到mAdded列表,和addFragment区别是,attachFragment只有在Fragment被detach之后才有意义,并且不需要makeActive,因为之前addFragment的时候已经做过了。

    public void attachFragment(Fragment fragment, int transition, int transitionStyle) {
        if (fragment.mDetached) {
            fragment.mDetached = false;
            if (!fragment.mAdded) {
                if (mAdded == null) {
                    mAdded = new ArrayList<Fragment>();
                }
                if (mAdded.contains(fragment)) {
                    throw new IllegalStateException("Fragment already added: " + fragment);
                }
                mAdded.add(fragment);
                fragment.mAdded = true;
                if (fragment.mHasMenu && fragment.mMenuVisible) {
                    mNeedMenuInvalidate = true;
                }
                moveToState(fragment, mCurState, transition, transitionStyle, false);
            }
        }
    }

7, detach
detachFragment会将Fragment从mAdded列表删除,并且把Fragment的状态置为CREATED,Fragment被detach的意义是指当前还在mActive列表里,UI并不显示出来,处于就绪状态,attach之后就会通过moveToState方法,使其的状态和FragmentManager的当前状态保持一致。
    public void detachFragment(Fragment fragment, int transition, int transitionStyle) {
        if (!fragment.mDetached) {
            fragment.mDetached = true;
            if (fragment.mAdded) {
                // We are not already in back stack, so need to remove the fragment.
                if (mAdded != null) {
                    mAdded.remove(fragment);
                }
                if (fragment.mHasMenu && fragment.mMenuVisible) {
                    mNeedMenuInvalidate = true;
                }
                fragment.mAdded = false;
                moveToState(fragment, Fragment.CREATED, transition, transitionStyle, false);
            }
        }
    }

Fragment的几个基本操作就分析完了,相信大家已经有比较深刻的了解了。总结一下,除了removeFragment和attachFragment会将Fragment的状态改为CREATED或者INITIALIZING,其他的操作都只是将Fragment的状态和FragmentManager保持一致。

再回到我们之前打算分析的Fragment的状态切换,Fragment在new出来时的状态是INITIALIZING,之后被加到FragmentManager之后,就和FragmentManager的状态一样了,直到被调用了removeFragment或者attachFragment,这时候Fragment就不再和FragmentManager一样,而是进入就绪状态(CREATED)或者初始化状态(INITIALIZING)。这两种状态的Fragment都UI不可见的,区别在于,前者还在Back Stack里,还可能会通过back键把当前的栈出栈而恢复,而后者则已经移除了Back Stack,只能通过addFragment再加入了。

最后我们分析重要方法moveToState,在这个方法里完成Fragment的状态切换,并完成Fragment的生命周期的调用。moveToState的方法比较长,
我们分几个阶段来分析:

1,预处理阶段
分析见注释
   void moveToState(Fragment f, int newState, int transit, int transitionStyle,
            boolean keepActive) {
        // 如果f被remove或者detach,那么moveToState后,Fragment的新的状态值最多只能到CREATED,因此只能是INITIALIZING或者CREATED
        if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
            newState = Fragment.CREATED;
        }
        // 如果f被remove了,那么不能再提升state
        if (f.mRemoving && newState > f.mState) {
            // While removing a fragment, we can't change it to a higher state.
            newState = f.mState;
        }
        // 如果当前start被defer,状态需为STOPPED,mDeferStart和LoaderManager机制有关,这里不展开分析,调用setUserVisibleHint可让Fragment的Start 被defer
        // 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;
        }
    ......
    ......
}

2,Fragment的状态切换
Fragment的状态切换有两个方向:一个是提升、一个是降低,我们从Fragment的状态位的定义可以看到,State值越大,表示Fragment越活跃,RESUMED=5表示在前台,INITIALIZING=0表示已经被删除。下面代码片段是moveToState的状态切换的整个框架,有意思的一点是switch的case是没有break的。当状态提升时,如果case到当前状态是INITIALIZING,而目标状态是STARTED,那么意味着将会走遍INITIALIZING,CREATED,ACTIVITY_CREATED,STOPPED,STARTED几个case,正是有了这种机制,使得在每个case只需要处理和他相邻的状态提升逻辑,比如INITIALIZING处理的是INITIALIZING->CREATED的状态切换,之后我们就逐个看每个case的状态切换。同理对于状态的降低也是一样的方式,只不过case的顺序是刚好倒过来。
    void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) {
        if (f.mState < newState) {
            switch (f.mState) {
                case Fragment.INITIALIZING:
                ......
                case Fragment.CREATED:
                ...... 
                case Fragment.ACTIVITY_CREATED:
                ......
                case Fragment.STOPPED:
                ......
                case Fragment.STARTED:
                ......
            }
        } else if (f.mState > newState) {
            switch (f.mState) {
                case Fragment.RESUMED:
                ......
                case Fragment.STARTED:
                ......
                case Fragment.STOPPED:
                case Fragment.ACTIVITY_CREATED:
                ......
                case Fragment.CREATED:
                ......
            }
        }       
        f.mState = newState;
    }
3,INITIALIZING提升到CREATED或更高
这个阶段包含Fragment的onAttach和onCreate生命周期,如果Fragment在layout文件里定义,还将走到onCreateView生命周期。Fragment的View管理,我们后面专门介绍,这里就不分析了。
                case Fragment.INITIALIZING:
                    if (f.mSavedFragmentState != null) {
                        // 这是Fragment状态恢复相关的,暂时不分析
                    }
                    f.mHost = mHost;
                    f.mParentFragment = mParent;
                    f.mFragmentManager = mParent != null
                            ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
                    f.mCalled = false;
                    // 执行Fragment的onAttach生命周期
                    f.onAttach(mHost.getContext());
                    if (!f.mCalled) {
                        throw new SuperNotCalledException("Fragment " + f
                                + " did not call through to super.onAttach()");
                    }
                    if (f.mParentFragment == null) {
                        mHost.onAttachFragment(f);
                    }
                    // 执行Fragment的onCreate生命周期
                    if (!f.mRetaining) {
                        f.performCreate(f.mSavedFragmentState);
                    }
                    f.mRetaining = false
                    if (f.mFromLayout) {
                        // 如果Fragment是在layout文件里定义的,那么就在这时执行Fragment的onCreateView生命周期
                        f.mView = f.performCreateView(f.getLayoutInflater(
                                f.mSavedFragmentState), null, f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.mView.setSaveFromParentEnabled(false);
                            if (f.mHidden) f.mView.setVisibility(View.GONE);
                            f.onViewCreated(f.mView, f.mSavedFragmentState);
                        }
                    }
4,CREATE提升到ACTIVITY_CREATED或者更高
这个阶段执行onCreateView,onActivityCreated生命周期

                case Fragment.CREATED:
                    if (newState > Fragment.CREATED) {
                        if (!f.mFromLayout) {   // 代码添加的Fragment,而不是layout文件定义的
                            ViewGroup container = null;
                            if (f.mContainerId != 0) {   // 找到Fragment的Container,用于addView
                                container = (ViewGroup)mContainer.onFindViewById(f.mContainerId);
                                if (container == null && !f.mRestored) {
                                    throwException(new IllegalArgumentException());
                                }
                            }
                            f.mContainer = container;
                            // 执行Fragment的onCreateView的生命周期
                            f.mView = f.performCreateView(f.getLayoutInflaterf.mSavedFragmentState), container, f.mSavedFragmentState);
                            if (f.mView != null) {
                                f.mView.setSaveFromParentEnabled(false);
                                if (container != null) {
                                    container.addView(f.mView);
                                }
                                if (f.mHidden) f.mView.setVisibility(View.GONE);
                                f.onViewCreated(f.mView, f.mSavedFragmentState);
                            }
                        }
                        // 执行Fragment的onActivityCreated生命周期
                        f.performActivityCreated(f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.restoreViewState(f.mSavedFragmentState);
                        }
                        f.mSavedFragmentState = null;
                    }
5,ACTIVITY_CREATED或者STOPPED提升至STARTED状态或者更高
执行onStart的生命周期
                case Fragment.ACTIVITY_CREATED:
                case Fragment.STOPPED:
                    if (newState > Fragment.STOPPED) {
                        if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
                        // 执行Fragment的onStart的生命周期
                        f.performStart();
                    }
6,STARTED状态提升至RESUMED
执行onResume的生命周期
                case Fragment.STARTED:
                    if (newState > Fragment.STARTED) {
                        if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
                        f.mResumed = true;
                        // 执行Fragment的onResume的生命周期
                        f.performResume();
                        // Get rid of this in case we saved it and never needed it.
                        f.mSavedFragmentState = null;
                        f.mSavedViewState = null;
                    }
7,降低状态是提升的逆过程,我们看RESUMED->STARTED->STOPPED的状态转化如下,分别执行onPause和onStop的生命周期
                case Fragment.RESUMED:
                    if (newState < Fragment.RESUMED) {
                        if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
                        // 执行Fragment的onPause生命周期
                        f.performPause();
                        f.mResumed = false;
                    }
                case Fragment.STARTED:
                    if (newState < Fragment.STARTED) {
                        if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
                        // 执行onStop生命周期
                        f.performStop();
                    }
8,STOPPED或ACTIVITY_CREATED -> CREATED状态
切换到CREATED状态时,就会把View从container里删除,所以CREATED状态的Fragment是没有UI的
    case Fragment.STOPPED:
    case Fragment.ACTIVITY_CREATED:
        if (newState < Fragment.ACTIVITY_CREATED) {  
            if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {  
                saveFragmentViewState(f);  
            } 
            // 执行Fragment的onDestroyView生命周期  
            f.performDestroyView();  
            if (f.mView != null && f.mContainer != null) {  
                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;  
                    ......  // 省略的部分是删除动画,这里不展开分析  
                }  
                f.mContainer.removeView(f.mView);  
            }  
            f.mContainer = null;  
            f.mView = null;  
        }  
9,CREATED-> INITIALIZING
这个阶段执行onDestroy和onDetach的生命周期
        case Fragment.CREATED:
            if (newState < Fragment.CREATED) {
                if (f.mAnimatingAway != null) { //如果退出动画还未结束,那么等动画结束之后再切换状态
                    f.mStateAfterAnimating = newState;
                    newState = Fragment.CREATED;
                } else 
                    if (!f.mRetaining) {
                        f.performDestroy(); //执行Fragment的onDestroy生命周期
                    }
                    f.mCalled = false;
                    f.onDetach();  //执行Fragment的onDetach生命周期
                    if (!f.mCalled) {
                        throw new SuperNotCalledException("Fragment " + " did not call through to super.onDetach()");
                    }
                    if (!keepActive) {
                        if (!f.mRetaining) {
                            makeInactive(f); //如果Fragment已经不在active了,就从mActive列表里删除
                        } else {
                            f.mHost = null;
                            f.mParentFragment = null;
                            f.mFragmentManager = null;
                            f.mChildFragmentManager = null;
                        }
                    }
                }
            }

到此,整个Fragment的生命周期的管理就介绍完了,下篇文章我们将介绍Fragment余下的几个部分的分析。


作者简介:

田力,网易彩票Android端创始人,小米视频创始人,现任roobo技术经理、视频云技术总监

欢迎关注微信公众号 磨剑石,定期推送技术心得以及源码分析等文章,谢谢




                                    
展开阅读全文

没有更多推荐了,返回首页