Fragment之底层关键操作函数moveToState

moveToState是FM中一个相当长的函数,但Fragment任何的操作add,remove …最终都会调用这个函数,从字面上可以理解,fragment要从当前状态切到newState里面干些什么都在这个函数中。
Fragment有六种State,初始状态是INITIALIZING:

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.

    int mState = INITIALIZING;

那么看看 对Fragment的各个操作分别是如何调用moveToState的。

操作 调用 说明
addFragment moveToState(fragment) 实质调用moveToState(f, mCurState, 0, 0, false);
attachFragment moveToState(fragment, mCurState, transition, transitionStyle, false);

可以看出,addFragment,attachFragment的newState都是向fm的域mCurState看齐的

mCurState的值是如何来的呢?

在fm中只有一处对mCurState进行赋值。

void moveToState(int newState, int transit, int transitStyle, boolean always) {
        if (mHost == null && newState != Fragment.INITIALIZING) {
            throw new IllegalStateException("No host");
        }

        if (!always && mCurState == newState) {
            return;
        }

        mCurState = newState;
        if (mActive != null) {
            boolean loadersRunning = false;
            for (int i=0; iif (f != null) {
                    moveToState(f, newState, transit, transitStyle, false);
                    if (f.mLoaderManager != null) {
                        loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                    }
                }
            }

            if (!loadersRunning) {
                startPendingDeferredFragments();
            }

            if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
                mHost.onSupportInvalidateOptionsMenu();
                mNeedMenuInvalidate = false;
            }
        }
    }

该函数被moveToState(int newState, boolean always)所调用,而后者又被

        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);
    }

那么上面这些函数又会被谁调用到呢?FragmentActivity!

FragmentActivity生命周期 fm被调用函数
onCreate dispatchCreate()
onStart() dispatchStart() 及 dispatchActivityCreated()
onStop() dispatchStop()
onPostResume() dispatchResume()

小结

fm中mCurState的值是完全随着其FragmentActivity生命周期变化而变化的,那么也就说明每当有fragment 添加进来的时候,其newState都是和其父FragmentActivity的当前生命周期是相对应的。

拆解moveToState结构

长长的函数,提炼一下

if (f.mState < newState) {
            switch (f.mState) {
                case Fragment.INITIALIZING:
                    //some code
                case Fragment.CREATED:
                    if (newState > Fragment.CREATED) {
                        //some code
                    }
                case Fragment.ACTIVITY_CREATED:
                case Fragment.STOPPED:
                    if (newState > Fragment.STOPPED) {
                        //some code
                    }
                case Fragment.STARTED:
                    if (newState > Fragment.STARTED) {
                        //some code
                    }
            }
        } else if (f.mState > newState) {
            switch (f.mState) {
                case Fragment.RESUMED:
                    if (newState < Fragment.RESUMED) {
                        //some code
                    }
                case Fragment.STARTED:
                    if (newState < Fragment.STARTED) {
                        //some code
                    }
                case Fragment.STOPPED:
                    if (newState < Fragment.STOPPED) {
                        //some code
                    }
                case Fragment.ACTIVITY_CREATED:
                    if (newState < Fragment.ACTIVITY_CREATED) {
                        //some code
                    }
                case Fragment.CREATED:
                    if (newState < Fragment.CREATED) {
                        //some code
                    }
            }
        }
        f.mState = newState;

小结

在switch的每个case里是没有添加break的,也就是从fragment当前的状态开始一直执行掉剩下的所有case,所以fragment添加后,不论其父FragmentActivity处于什么状态,他都会从头执行自己的生命周期。

分析每个状态干了些啥

当fragment刚添加到父组件中时,f.mState < newState

Fragment.INITIALIZING

f.mHost = mHost;
                    f.mParentFragment = mParent;
                    f.mFragmentManager = mParent != null
                            ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
                    f.mCalled = false;
                    f.onAttach(mHost.getContext());

之前fragmnet是一个完全独立的对象,和父Fragment或父FragmentActivity一点关系没有,那么经过了INITIALIZING这一步,算是认祖归宗了。那么onAttach的意义也在于此。
而后在fragment.mFromLayout条件为true时会执行如下代码

if (!f.mRetaining) {
            f.performCreate(f.mSavedFragmentState);
        }

        f.mView = f.performCreateView(f.getLayoutInflater(
                f.mSavedFragmentState), null, f.mSavedFragmentState);
        if (f.mView != null) {
/* some code */
            f.onViewCreated(f.mView, f.mSavedFragmentState);
        }

通过performCreateView间接回调onCreateView得到fragment的View,拿到该View后就会回调onViewCreated

Fragment.CREATED

而后在fragment.mFromLayout条件为false时会执行:
根据mContainerId得到View容器container,并且将fragment的onCreateView所返回的View添加到容器container中。
而后顺序调用
f.onViewCreated(f.mView, f.mSavedFragmentState)

f.performActivityCreated(f.mSavedFragmentState)

Fragment.ACTIVITY_CREATED,Fragment.STOPPED,Fragment.STARTED没有什么实质的工作,走了个过场。

小结

上面的过程基本上可以一览fragment的添加过程:
1.将fragment和父组件关联起来。
2.将fragment中的View添加到父组件的View容器中,这样就能显示出fragment的View出来了。

你可能感兴趣的:(Android)