FragmentManagerImpl

field

    static final boolean HONEYCOMB = android.os.Build.VERSION_SDK >=11;

    static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
    static final String TARGET_STATE_TAG = "android:target_state";
    static final String VIEW_STATE_TAG = "android:view_state";
    static final String USER_VISIBLE_HINT_TAG="android:user_visible_hint";

    //
    ArrayList<Runnable> mPendingActions;
    Runnable[] mTmpActions;
    boolean mExectingActions

    //当前在所有有效的fragment实例
    ArrayList<Fragment> mActive;
    //当前Activity上所添加的Activity
    ArrayList<Fragment> mAdded;

    ArrayList<Integer> mAvailIndices;
    ArrayList<BackStackRecord> mBackStack;
    ArrayList<Fragment> mCreatedMenus;

    // Must be accessed while locked.
    ArrayList<BackStackRecord> mBackStackIndices;
    ArrayList<Integer> mAvailBackStackIndices;

    ArrayList<OnBackStackChangedListener> mBackStackChangeListeners;

    int mCurState = Fragment.INITIALIZING;
    FragmentActivity mActivity;
    FragmentContainer mContainer;
    Fragment mParent;


    boolean mNeedMenuInvalidate;
    boolean mStateSaved;
    boolean mDestroyed;
    String mNoTransactionsBecause;
    boolean mHavePendingDeferredStart;

    // Temporary vars for state save and restore.
    Bundle mStateBundle = null;
    SparseArray<Parcelable> mStateArray = null;

    Runnable mExecCommit = new Runnable() {
        @Override
        public void run() {
            execPendingActions();
        }
    };
mActive
//在addFragment()中调用
void makeActive(Fragment f){
    if(f.mIndex >= 0)
        return;

    if(mAvailIndices == null ||mAvailIndices.size() <= 0){
    if(mActive == null){
        mActive = new ArrayList<Fragment>();
    }
    f.setIndex(mActive.size(),mParent);
    mActive.add(f);

    }else{
        f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1), mParent);
            mActive.set(f.mIndex, f);
    }
}

void makeInactive(Fragment f) {
        if (f.mIndex < 0) {
            return;
        }

        if (DEBUG) Log.v(TAG, "Freeing fragment index " + f);
        mActive.set(f.mIndex, null);
        if (mAvailIndices == null) {
            mAvailIndices = new ArrayList<Integer>();
        }
        mAvailIndices.add(f.mIndex);
        mActivity.invalidateSupportFragment(f.mWho);
        f.initState();
    }
mAdded

当前fragmentManager所添加的Fragment列表

public void addFragment(...){
    if(mAdded == null)
        mAdded = new ArrayList<Fragment>();
    ...
    makeActive(fragment);
    if(!fragment.mDetached){
        ...
        mAdded.add(fragment);
        fragment.mAdded = true;
        fragment.mRemoving = false;
        ...
    }
}

public void removeFragment(...){
    ...
    if(!fragment.mDeatched || inactive){
        if(mAdded != null)
            mAdded.remove(fragment);
        ...
        fragment.mAdded = false;
        fragment.mRemoving = true;
        ...
    }
    ...
}

public void attachFragment(...){
    if(fragment.mDetached){
        fragment.mDetached = false;

        if(!fragment.mAdded){
            if(mAdded == null){
                mAdded = new ArrayList<Fragment>();
            }
            ...
            mAdded.add(fragment);
            fragment.mAdded = true;
            ...
        }
    }
}

public void detachFragment(...){
    if(!fragment.mDetached){
        fragment.mDetached = true;
        if(fragment.mAdded){
            if(mAdded != null){
                mAdded.remove(fragment);
            }
            ...
            fragment.mAdded = false;
            ...
        }
    }
}

method

beginTransaction

//返回BackStackRecord对象
@Override
    public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
    }

executePendingTransactions和execPendingActions


    //commit后在主线程执行此方法开始分发操作并执行
    @Override
    public boolean executePendingTransactions() {
        return execPendingActions();
    }

    //只能从主线程调用execPendingActions方法
    public boolean execPendingActions(){

        //正在分发操作的线程时不能调用此方法
         if (mExecutingActions) {
            throw new IllegalStateException("Recursive entry to executePendingTransactions");
        }
        //不在主线程不能执行此操作
        if (Looper.myLooper() != mActivity.mHandler.getLooper()) {
            throw new IllegalStateException("Must be called from main thread of process");
        }

        //如果有操作线程被执行则返回true
        boolean didSomething = false;

        //开启死循环检测分发要执行的操作,当没有要分发的操作时退出循环
        while(true){
         int numActions;

            synchronized (this) {
                if (mPendingActions == null || mPendingActions.size() == 0) {
                    break;
                }

                numActions = mPendingActions.size();
                if (mTmpActions == null || mTmpActions.length < numActions) {
                    mTmpActions = new Runnable[numActions];
                }
                mPendingActions.toArray(mTmpActions);
                mPendingActions.clear();
                mActivity.mHandler.removeCallbacks(mExecCommit);
            }

            mExecutingActions = true;
            for (int i=0; i<numActions; i++) {
                mTmpActions[i].run();
                mTmpActions[i] = null;
            }
            mExecutingActions = false;
            didSomething = true;
        }

        //判断是否有延迟启动的fragment并启动?
        if (mHavePendingDeferredStart) {
            boolean loadersRunning = false;
            for (int i=0; i<mActive.size(); i++) {
                Fragment f = mActive.get(i);
                if (f != null && f.mLoaderManager != null) {
                    loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                }
            }
            if (!loadersRunning) {
                mHavePendingDeferredStart = false;
                startPendingDeferredFragments();
            }
        }
        return didSomething;
    }

popBackStack

    //弹出栈顶的fragment,但这个方法是异步操作的
    @Override
    public void popBackStack() {
        enqueueAction(new Runnable() {
            @Override public void run() {
                popBackStackState(mActivity.mHandler, null, -1, 0);
            }
        }, false);
    }

    boolean popBackStackState(Handler handler,String name,int id,int flags){
        //后退栈为null时返回
        if(mbackStack == null)
            rerturn false;

        //如果name == null 并且 id < 0 并且 flag = 0时,弹出栈顶fragment
        if(name == null && id < 0 && (flags&POP_BACK_STACK_INCLUSIVE) == 0){
            ...
        }
        //否则,根据name或者id找到对应的fragment,
        //  找不到就返回,
        //  找到后根据flag判断弹出fragment时是否包括指定的fragment
        else{
            int index = -1//定位到指定fragment
            if (name != null || id >= 0) {
                // If a name or ID is specified, look for that place in
                // the stack.
                index = mBackStack.size()-1;
                while (index >= 0) {
                    BackStackRecord bss = mBackStack.get(index);
                    if (name != null && name.equals(bss.getName())) {
                        break;
                    }
                    if (id >= 0 && id == bss.mIndex) {
                        break;
                    }
                    index--;
                }
                if (index < 0) {
                    return false;
                }

                //flag == 1时 定位到下一个fragment,并向下查找直到找到指定的fragment
                if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) {
                    index--;
                    // Consume all following entries that match.
                    while (index >= 0) {
                        BackStackRecord bss = mBackStack.get(index);
                        if ((name != null && name.equals(bss.getName()))
                                || (id >= 0 && id == bss.mIndex)) {
                            index--;
                            continue;
                        }
                        break;
                    }
                }
            }

            //没有找到 返回
            if (index == mBackStack.size()-1) {
                return false;
            }

            //把要删除的fragment存储在临时变量 states中
            final ArrayList<BackStackRecord> states
                    = new ArrayList<BackStackRecord>();
            for (int i=mBackStack.size()-1; i>index; i--) {
                states.add(mBackStack.remove(i));
            }

            //计算要返回删除的fragment
            final int LAST = states.size()-1;
            SparseArray<Fragment> firstOutFragments = new SparseArray<Fragment>();
            SparseArray<Fragment> lastInFragments = new SparseArray<Fragment>();
            for (int i=0; i<=LAST; i++) {
                states.get(i).calculateBackFragments(firstOutFragments, lastInFragments);
            }

            //开始删除
            BackStackRecord.TransitionState state = null;
            for (int i=0; i<=LAST; i++) {
                if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i));
                state = states.get(i).popFromBackStack(i == LAST, state,
                        firstOutFragments, lastInFragments);
            }

            //更新onBackStackChanged函数
            reportBackStackChanged();

        }
    }

saveFragmentInstanceState

@Override
    public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) {
        if (fragment.mIndex < 0) {
            throwException( new IllegalStateException("Fragment " + fragment
                    + " is not currently in the FragmentManager"));
        }
        if (fragment.mState > Fragment.INITIALIZING) {
            Bundle result = saveFragmentBasicState(fragment);
            return result != null ? new Fragment.SavedState(result) : null;
        }
        return null;
    }

     Bundle saveFragmentBasicState(Fragment f) {
        Bundle result = null;

        if (mStateBundle == null) {
            mStateBundle = new Bundle();
        }
        f.performSaveInstanceState(mStateBundle);
        if (!mStateBundle.isEmpty()) {
            result = mStateBundle;
            mStateBundle = null;
        }

        if (f.mView != null) {
            saveFragmentViewState(f);
        }
        if (f.mSavedViewState != null) {
            if (result == null) {
                result = new Bundle();
            }
            result.putSparseParcelableArray(
                    FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
        }
        if (!f.mUserVisibleHint) {
            if (result == null) {
                result = new Bundle();
            }
            // Only add this if it's not the default value
            result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
        }

        return result;
    }

moveToState方法

调用moveToState的函数

public void addFragment(Fragment fragment,boolean moveToStateNow){
    ...
    if(moveToStateNow)
        moveToState(fragment);
    ...
}

public void removeFragment (Fragment fragment,int transit,int transitStyle){
    ...
    moveToState(fragment,inactive ? Fragment.INITIALIAING : Fragment.CREATED,transit,transitStyle,false);
    ...
}

public void detachFragment(Fragment fragment,int transit,int transitStyle){
    ...
    moveToState(fragment,Fragment.CREATED,transit,transitStyle,false);
    ...
}

public attachFragment(Fragment fragment,int transit,int transitStyle){
    ...
    moveToState(fragment,mCurState,transit,transitStyle,false);
    ...
}

public void dispatchCreate(){
    mStateSaved = false;
    moveToState(Fragment.CREATED,false);
}

public void dispatchActivityCreate(){
    mStateSaved = false;
    moveToState(Fragment.Activity_CRAETED,false);
}

public void dispatchStart(){
    ...
    moveToState(Fragment.STARTED,false);
}

public void dispatchResume(){
    ...
    moveToState(Fragment.RESUMED,false);
}

public void dispatchPause(){
    ...
    moveToState(Fragment.STARTED,false);
}

public void dispacthStop(){
    ...
    moveToState(Fragment.STOPPED,false);
}

public void dispatchReallyStop(){
    ...
    moveToState(Fragment.ACTIVITY_CREATED,false);
}

public void dispatchDestroyView(){
    ...
    moveToState(Fragment.CREATED,false);
}

public void dispatchDestroy(){
    ...
    moveToState(Fragment.INITIALIZING,false);
}

public void onCreateView(String name,Context context,AttributeSet attrs){
    ...
    if (mCurState < Fragment.CREATED && fragment.mFromLayout) {
            moveToState(fragment, Fragment.CREATED, 0, 0, false);
        } else {
            moveToState(fragment);
        }
}

public void performPendingDeferredStart(Fragment f){
    ...
    moveToState(f, mCurState, 0, 0, false);
    ...
}

moveToState

Fragment内部关于生命周期的几个常量

    static final int INITIALIZING = 0;     // Not yet created.fragment没有被初始化
    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.

dispatch**方法中调用moveToState(int,boolean);

dispatch** 常量
dispatchCreate() CREATED 1
dispatchActivityCreated() ACTIVITY_CREATED 2
dispatchStart() STARTED 4
dispatchResume() RESUMED 5
dispatchPause() STARTED 4
dispatchStop() STOPPED 3
dispatchReallyStop() ACTIVITY_CREATED 2
dispatchDestroyView() CREATED 1
dispatchDestroy() INITIALIZING 0
void moveToState(Fragment f){
    //调用moteToState(Fragment,int,int,int,boolean)方法
    moveToState(f,mCurState,0,0,false);
}

//该方法在dispatch**中调用
void moveToState(int newState,boolean always){
    //调用moveToState(Fragment,int,int,boolean)
    moveToState(newState,0,0,always);
}

//调用该方法时会遍历更新mActive内部存储的fragment
void moveToState(int newState,int transit,int transitStyle,boolean always){
    ...
    //调用最终的方法
    moveToState(f, newState, transit, transitStyle, false);
    ...
}

void moveToState(Fragment f,int newState,int transit,int transitStyle,boolean keepAlive){
    ...
}
 void moveToState(int newState, int transit, int transitStyle, boolean always) {

        if (mActivity == null && newState != Fragment.INITIALIZING) {
            throw new IllegalStateException("No activity");
        }

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

        //在此次更新mActive列表内的fragment状态
        mCurState = newState;
        if (mActive != null) {
            boolean loadersRunning = false;
            for (int i=0; i<mActive.size(); i++) {
                Fragment f = mActive.get(i);
                if (f != null) {
                    moveToState(f, newState, transit, transitStyle, false);
                    if (f.mLoaderManager != null) {
                        loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                    }
                }
            }

            if (!loadersRunning) {
                startPendingDeferredFragments();
            }

            if (mNeedMenuInvalidate && mActivity != null && mCurState == Fragment.RESUMED) {
                mActivity.supportInvalidateOptionsMenu();
                mNeedMenuInvalidate = false;
            }
        }
    }
void moveToState(Fragment f,int newState,int transit,int transitionStyle,boolean keepAlive){
    //学习ing...
     // Fragments that are not currently added will sit in the onCreate() state.
        if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
            newState = Fragment.CREATED;
        }
        if (f.mRemoving && newState > f.mState) {
            // While removing a fragment, we can't change it to a higher state.
            newState = f.mState;
        }
        // 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;
        }
        if (f.mState < newState) {
            // For fragments that are created from a layout, when restoring from
            // state we don't want to allow them to be created until they are
            // being reloaded from the layout.
            if (f.mFromLayout && !f.mInLayout) {
                return;
            }
            if (f.mAnimatingAway != null) {
                // The fragment is currently being animated...  but!  Now we
                // want to move our state back up.  Give up on waiting for the
                // animation, move to whatever the final state should be once
                // the animation is done, and then we can proceed from there.
                f.mAnimatingAway = null;
                moveToState(f, f.mStateAfterAnimating, 0, 0, true);
            }
            switch (f.mState) {
                case Fragment.INITIALIZING:
                    if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
                    if (f.mSavedFragmentState != null) {
                        f.mSavedFragmentState.setClassLoader(mActivity.getClassLoader());
                        f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
                                FragmentManagerImpl.VIEW_STATE_TAG);
                        f.mTarget = getFragment(f.mSavedFragmentState,
                                FragmentManagerImpl.TARGET_STATE_TAG);
                        if (f.mTarget != null) {
                            f.mTargetRequestCode = f.mSavedFragmentState.getInt(
                                    FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
                        }
                        f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
                                FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
                        if (!f.mUserVisibleHint) {
                            f.mDeferStart = true;
                            if (newState > Fragment.STOPPED) {
                                newState = Fragment.STOPPED;
                            }
                        }
                    }
                    f.mActivity = mActivity;
                    f.mParentFragment = mParent;
                    f.mFragmentManager = mParent != null
                            ? mParent.mChildFragmentManager : mActivity.mFragments;
                    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);
                    }

                    if (!f.mRetaining) {
                        f.performCreate(f.mSavedFragmentState);
                    }
                    f.mRetaining = false;
                    if (f.mFromLayout) {
                        // For fragments that are part of the content view
                        // layout, we need to instantiate the view immediately
                        // and the inflater will take care of adding it.
                        f.mView = f.performCreateView(f.getLayoutInflater(
                                f.mSavedFragmentState), null, f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.mInnerView = f.mView;
                            f.mView = NoSaveStateFrameLayout.wrap(f.mView);
                            if (f.mHidden) f.mView.setVisibility(View.GONE);
                            f.onViewCreated(f.mView, f.mSavedFragmentState);
                        } else {
                            f.mInnerView = null;
                        }
                    }
                case Fragment.CREATED:
                    if (newState > Fragment.CREATED) {
                        if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
                        if (!f.mFromLayout) {
                            ViewGroup container = null;
                            if (f.mContainerId != 0) {
                                container = (ViewGroup)mContainer.findViewById(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.mInnerView = f.mView;
                                f.mView = NoSaveStateFrameLayout.wrap(f.mView);
                                if (container != null) {
                                    Animation anim = loadAnimation(f, transit, true,
                                            transitionStyle);
                                    if (anim != null) {
                                        f.mView.startAnimation(anim);
                                    }
                                    container.addView(f.mView);
                                }
                                if (f.mHidden) f.mView.setVisibility(View.GONE);
                                f.onViewCreated(f.mView, f.mSavedFragmentState);
                            } else {
                                f.mInnerView = null;
                            }
                        }

                        f.performActivityCreated(f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.restoreViewState(f.mSavedFragmentState);
                        }
                        f.mSavedFragmentState = null;
                    }
                case Fragment.ACTIVITY_CREATED:
                case Fragment.STOPPED:
                    if (newState > Fragment.STOPPED) {
                        if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
                        f.performStart();
                    }
                case Fragment.STARTED:
                    if (newState > Fragment.STARTED) {
                        if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
                        f.mResumed = true;
                        f.performResume();
                        f.mSavedFragmentState = null;
                        f.mSavedViewState = null;
                    }
            }
        } else if (f.mState > newState) {
            switch (f.mState) {
                case Fragment.RESUMED:
                    if (newState < Fragment.RESUMED) {
                        if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
                        f.performPause();
                        f.mResumed = false;
                    }
                case Fragment.STARTED:
                    if (newState < Fragment.STARTED) {
                        if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
                        f.performStop();
                    }
                case Fragment.STOPPED:
                    if (newState < Fragment.STOPPED) {
                        if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
                        f.performReallyStop();
                    }
                case Fragment.ACTIVITY_CREATED:
                    if (newState < Fragment.ACTIVITY_CREATED) {
                        if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
                        if (f.mView != null) {
                            // Need to save the current view state if not
                            // done already.
                            if (!mActivity.isFinishing() && f.mSavedViewState == null) {
                                saveFragmentViewState(f);
                            }
                        }
                        f.performDestroyView();
                        if (f.mView != null && f.mContainer != null) {
                            Animation anim = null;
                            if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
                                anim = loadAnimation(f, transit, false,
                                        transitionStyle);
                            }
                            if (anim != null) {
                                final Fragment fragment = f;
                                f.mAnimatingAway = f.mView;
                                f.mStateAfterAnimating = newState;
                                anim.setAnimationListener(new AnimationListener() {
                                    @Override
                                    public void onAnimationEnd(Animation animation) {
                                        if (fragment.mAnimatingAway != null) {
                                            fragment.mAnimatingAway = null;
                                            moveToState(fragment, fragment.mStateAfterAnimating,
                                                    0, 0, false);
                                        }
                                    }
                                    @Override
                                    public void onAnimationRepeat(Animation animation) {
                                    }
                                    @Override
                                    public void onAnimationStart(Animation animation) {
                                    }
                                });
                                f.mView.startAnimation(anim);
                            }
                            f.mContainer.removeView(f.mView);
                        }
                        f.mContainer = null;
                        f.mView = null;
                        f.mInnerView = null;
                    }
                case Fragment.CREATED:
                    if (newState < Fragment.CREATED) {
                        if (mDestroyed) {
                            if (f.mAnimatingAway != null) {
                                // The fragment's containing activity is
                                // being destroyed, but this fragment is
                                // currently animating away.  Stop the
                                // animation right now -- it is not needed,
                                // and we can't wait any more on destroying
                                // the fragment.
                                View v = f.mAnimatingAway;
                                f.mAnimatingAway = null;
                                v.clearAnimation();
                            }
                        }
                        if (f.mAnimatingAway != null) {
                            // We are waiting for the fragment's view to finish
                            // animating away.  Just make a note of the state
                            // the fragment now should move to once the animation
                            // is done.
                            f.mStateAfterAnimating = newState;
                            newState = Fragment.CREATED;
                        } else {
                            if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
                            if (!f.mRetaining) {
                                f.performDestroy();
                            }

                            f.mCalled = false;
                            f.onDetach();
                            if (!f.mCalled) {
                                throw new SuperNotCalledException("Fragment " + f
                                        + " did not call through to super.onDetach()");
                            }
                            if (!keepActive) {
                                if (!f.mRetaining) {
                                    makeInactive(f);
                                } else {
                                    f.mActivity = null;
                                    f.mParentFragment = null;
                                    f.mFragmentManager = null;
                                    f.mChildFragmentManager = null;
                                }
                            }
                        }
                    }
            }
        }

        f.mState = newState;
}
关于moveToState以下表格参考 support-v4-23.0.1
当前状态 当前状态值 命令 执行 生命周期变动
INITIALIZING 0 1 onAttch
onCreate
OnAttch
OnCreate
CREATED 1 2 createview onCreateView
onActivityCreated
ACTIVITY_CREATED 2 3
STOPPED 3 4 performStart onStart
STARTED 4 5 performResume onResume
RESUMED 5 4 pause onPause
STARTED 4 3 stop onStop
STOPPED 3 2 reallyStop
ACTIVITY_CREATED 2 1 destroyView onDestroyView
CREATED 1 0 destroy onDestroy
onDetach

results matching ""

    No results matching ""