Fragment狀態變化,觸發了哪些方法

1、追蹤FragmentManager對Fragment操做涉及到方法

getSupportFragmentManager().beginTransaction().remove(Fragment fragment).commit()java

BackStackRecord remove(Fragment fragment)
BackStackRecord.commit() // 開始
BackStackRecord.commitInternal(boolean allowStateLoss)

FragmentManagerImpl.enqueueAction(OpGenerator action, boolean allowStateLoss)
// 涉及到Handler的延時處理
FragmentManager.scheduleCommit() {
        synchronized (this) {
            boolean postponeReady =
                    mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
            boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
            if (postponeReady || pendingReady) {
                mHost.getHandler().removeCallbacks(mExecCommit);
                mHost.getHandler().post(mExecCommit);
            }
        }
}

handler將進一步操做Runnableide

Runnable mExecCommit = new Runnable() {
        @Override
        public void run() {
            execPendingActions();
        }
    };

FragmentManager.execPendingActions()
FragmentManager.doPendingDeferredStart()
FragmentManager.startPendingDeferredFragments()
FragmentManager.performPendingDeferredStart(Fragment f)
FragmentManager.moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive){
   case Fragment.ACTIVITY_CREATED:
       onDestroyView();
       mContainer.removeView(f.mView)
       f.view.dispatchDetachedFromWindow();
       f.mContainer = null;
       f.mView = null;
   case Fragment.CREATED:
       f.performDestroy();
       f.performDetach();
       makeInactive(f);
       f.mHost = null;
}

moveToState 是狀態變化的核心方法,須要進一步查看源碼post

2、FragmentManager.moveToState解析

FragmentActivity維護着FragmentManager一個實例,而FragmentManager管理者Fragment的各個狀態, 查看FragmentManagerImpl源碼中this

FragmentManagerImpl{
 int mCurState = Fragment.INITIALIZING; //初始化狀態
}

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.
}

mCurState就是當前FragmentManager的狀態,mCurState只有一個方法中對其有賦值操做moveToState(int newState, boolean always)而這個方法調用處以下:spa

public void dispatchCreate() {
        mStateSaved = false;
        mStopped = false;
        dispatchStateChange(Fragment.CREATED);
    }

    public void dispatchActivityCreated() {
        mStateSaved = false;
        mStopped = false;
        dispatchStateChange(Fragment.ACTIVITY_CREATED);
    }

    public void dispatchStart() {
        mStateSaved = false;
        mStopped = false;
        dispatchStateChange(Fragment.STARTED);
    }

    public void dispatchResume() {
        mStateSaved = false;
        mStopped = false;
        dispatchStateChange(Fragment.RESUMED);
    }

    public void dispatchPause() {
        dispatchStateChange(Fragment.STARTED);
    }

    public void dispatchStop() {
        mStopped = true;
        dispatchStateChange(Fragment.STOPPED);
    }

方法對應着狀態值的調整,看命名好像和Activity的生命週期對於,咱們再對照FragmentActivity的源碼code

public void dispatchCreate() {
        mHost.mFragmentManager.dispatchCreate();
    }

    public void dispatchActivityCreated() {
        mHost.mFragmentManager.dispatchActivityCreated();
    }

    public void dispatchStart() {
        mHost.mFragmentManager.dispatchStart();
    }

    public void dispatchResume() {
        mHost.mFragmentManager.dispatchResume();
    }

    public void dispatchPause() {
        mHost.mFragmentManager.dispatchPause();
    }

    public void dispatchStop() {
        mHost.mFragmentManager.dispatchStop();
    }

果真是由Activity來觸發FragmentManager的狀態變化 接下來詳細看下FragmentManager.moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive)方法 簡化以下:orm

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;

在每一個case中都沒有break,則會順序執行,主要是fragment狀態和FragmentManager的狀態進行了對比,生命週期

  • 1)fragment狀態小於FragmentManager的狀態,相似Activity已完成初始化,用戶點擊操做,開始addFragment,則開始順序執行初始化Fragment的狀態;
  • 2)fragment狀態大於FragmentManager的狀態,相似Activity已完成初始化,用戶點擊操做,開始removeFragment,則開始刪除Fragment 最終Fragment狀態和FragmentManager的狀態同步
相關文章
相關標籤/搜索