AndroidX Fragment探究-事务操作

994 阅读20分钟

概述

平时开发中经常使用Fragment的场景是创建Fragment并添加到FragmentActivity的指定布局容器中。要实现这样的操作,首先需要获取FragmentManager,接着开启事务FragmentTransaction,并添加add、remove、replace、hide、show等等操作,最后commitXXX提交事务执行对应操作。

接下来进入源码追踪这个过程,看看FragmentManager是如何进行调度执行。

源码探究

文中源码基于'androidx.fragment:fragment:1.1.0'

FragmentManager的由来

在FragmentActivity中通过getSupportFragmentManager方法来获取FragmentManager:

[FragmentActivity.java]

public FragmentManager getSupportFragmentManager() {
    return mFragments.getSupportFragmentManager();
}

该方法中又通过mFragments成员来获取: [FragmentController.java]

public FragmentManager getSupportFragmentManager() {
    return mHost.mFragmentManager;
}

其中又通过mHost成员来获取。

在研究FragmentManager之前,先来看看mFragments、mHost是什么。

FragmentController

先来看看FragmentActivity的mFragments成员:

[FragmentActivity.java]

public class FragmentActivity extends ComponentActivity implements
        ActivityCompat.OnRequestPermissionsResultCallback,
        ActivityCompat.RequestPermissionsRequestCodeValidator {
    // ···
    final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
    // ···
}

mFragments为FragmentController对象。

接着看createController方法,这里传入HostCallbacks实例: [FragmentController.java]

public static FragmentController createController(@NonNull FragmentHostCallback<?> callbacks) {
    return new FragmentController(checkNotNull(callbacks, "callbacks == null"));
}

private FragmentController(FragmentHostCallback<?> callbacks) {
    // 持有HostCallbacks引用
    mHost = callbacks;
}

HostCallbacks

在创建FragmentController时,实例化了HostCallbacks并赋值给FragmentController的mHost成员。

[FragmentActivity.java]

class HostCallbacks extends FragmentHostCallback<FragmentActivity> implements
        ViewModelStoreOwner,
        OnBackPressedDispatcherOwner {
    public HostCallbacks() {
        super(FragmentActivity.this /*fragmentActivity*/);
    }
    // ···
}

HostCallbacks继承自FragmentHostCallback,为FragmentActivity的内部类,持有FragmentActivity的引用。

[FragmentHostCallback.java]

public abstract class FragmentHostCallback<E> extends FragmentContainer {
    // ···
    FragmentHostCallback(@NonNull FragmentActivity activity) {
        this(activity, activity /*context*/, new Handler(), 0 /*windowAnimations*/);
    }

    FragmentHostCallback(@Nullable Activity activity, @NonNull Context context,
            @NonNull Handler handler, int windowAnimations) {
        // 持有FragmentActivity上下文引用
        mActivity = activity;
        mContext = Preconditions.checkNotNull(context, "context == null");
        // 构造函数中创建的Handler,默认运行在主线程
        mHandler = Preconditions.checkNotNull(handler, "handler == null");
        // 动画相关,默认为0
        mWindowAnimations = windowAnimations;
    }
    // ···
}

可以看出HostCallbacks持有当前FragmentActivity上下文,并创建了一个主线程Handler。

FragmentManagerImpl

FragmentManager为抽象类,而FragmentManagerImpl是其实现类:

[FragmentManagerImpl.java]

final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 {
    // ···
}

在FragmentHostCallback实例化时会创建FragmentManagerImpl: [FragmentHostCallback.java]

public abstract class FragmentHostCallback<E> extends FragmentContainer {
    // ···
    final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
    // ···
}

FragmentHostCallback的mFragmentManager成员持有FragmentManagerImpl。

FragmentManagerImpl的绑定

在FragmentActivity的onCreate方法中: [FragmentActivity.java]

protected void onCreate(@Nullable Bundle savedInstanceState) {
    // 调用FragmentController的attachHost方法,参数传null
    mFragments.attachHost(null /*parent*/);
    // ···
}

接着看attachHost方法: [FragmentController.java]

public void attachHost(@Nullable Fragment parent) {
    // 调用FragmentManagerImpl的attachController方法,并传入HostCallbacks实例,参数parent为null。
    mHost.mFragmentManager.attachController(
            mHost, mHost /*container*/, parent);
}

进入FragmentManagerImpl的attachController方法: [FragmentManagerImpl.java]

public void attachController(@NonNull FragmentHostCallback host,
        @NonNull FragmentContainer container, @Nullable final Fragment parent) {
    if (mHost != null) throw new IllegalStateException("Already attached");
    // 持有HostCallbacks引用
    mHost = host;
    mContainer = container;
    mParent = parent;
    if (mParent != null) {
        // Since the callback depends on us being the primary navigation fragment,
        // update our callback now that we have a parent so that we have the correct
        // state by default
        updateOnBackPressedCallbackEnabled();
    }
    // Set up the OnBackPressedCallback
    // 省略BackPressed设置部分
    // ···
    
    // Get the FragmentManagerViewModel
    // 省略ViewModel设置部分
    // ···
}

FragmentActivity在onCreate中进行FragmentManagerImpl的绑定操作,在FragmentManagerImpl的attachController方法中接收HostCallbacks实例并保存。

FragmentController、HostCallbacks、FragmentManagerImpl之间关系

FragmentController类图

FragmentActivity持有FragmentController引用,FragmentController持有HostCallbacks引用,HostCallbacks持有FragmentActivity引用,FragmentActivity和FragmentManagerImpl互相持有引用。

FragmentActivity通过FragmentController获取HostCallbacks,再通过HostCallbacks间接调用FragmentManagerImpl。FragmentManagerImpl通过HostCallbacks来间接获取上下文和执行回调方法。

添加事务操作

开启事务

获取到FragmentManagerImpl实例后,通过它的beginTransaction方法开启一个事务: [FragmentManagerImpl.java]

public FragmentTransaction beginTransaction() {
    return new BackStackRecord(this);
}

这里创建BackStackRecord(继承自FragmentTransaction,并实现BackStackEntry、OpGenerator接口),BackStackRecord将持有FragmentManagerImpl。

FragmentTransaction封装一个事务,一个事务包含一组操作(单个或多个操作)。

添加add Fragment的操作

这里以,往FragmentActivity中添加一个Fragment为例。

通常添加Fragment是通过调用FragmentTransaction的add方法,传入布局ID和Fragment实例: [FragmentTransaction.java]

public FragmentTransaction add(@IdRes int containerViewId, @NonNull Fragment fragment,
        @Nullable String tag) {
    // tag可选参数,可通过tag查找fragment,OP_ADD标识add操作类型
    doAddOp(containerViewId, fragment, tag, OP_ADD);
    return this;
}

BackStackRecord重写了doAddOp方法: [BackStackRecord.java]

void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
    super.doAddOp(containerViewId, fragment, tag, opcmd);
    // 将持有的FragmentManagerImpl赋值给Fragment的mFragmentManager成员
    fragment.mFragmentManager = mManager;
}

该方法中通过super还是调用FragmentTransaction的doAddOp,只是在执行完后为Fragment的mFragmentManager成员赋值。

[FragmentTransaction.java]

void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
    final Class<?> fragmentClass = fragment.getClass();
    final int modifiers = fragmentClass.getModifiers();
    // 检查fragment是否是匿名类,或者非public访问性,或者定义在另一个类中但没有声明static
    if (fragmentClass.isAnonymousClass() || !Modifier.isPublic(modifiers)
            || (fragmentClass.isMemberClass() && !Modifier.isStatic(modifiers))) {
        throw new IllegalStateException("Fragment " + fragmentClass.getCanonicalName()
                + " must be a public static class to be  properly recreated from"
                + " instance state.");
    }

    if (tag != null) {
        // 检查是否fragment已有tag但和当前传入的tag不同
        if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
            throw new IllegalStateException("Can't change tag of fragment "
                    + fragment + ": was " + fragment.mTag
                    + " now " + tag);
        }
        // fragment保存tag
        fragment.mTag = tag;
    }

    // containerViewId即为FragmentActivity中用于添加这个fragment的布局容器ID
    if (containerViewId != 0) {
        if (containerViewId == View.NO_ID) {
            throw new IllegalArgumentException("Can't add fragment "
                    + fragment + " with tag " + tag + " to container view with no id");
        }
        // 检查是否fragment已经设置容器ID但与当前传入的ID不同
        if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
            throw new IllegalStateException("Can't change container ID of fragment "
                    + fragment + ": was " + fragment.mFragmentId
                    + " now " + containerViewId);
        }
        // fragment保存容器ID,mFragmentId默认为容器ID
        fragment.mContainerId = fragment.mFragmentId = containerViewId;
    }
    
    // 添加操作
    addOp(new Op(opcmd, fragment));
}

该方法中做了以下几步:

  1. 该方法中首先校验我们自定义的Fragment:
  • 不能是匿名类
  • 访问性必须是public
  • 若是成员类,必须是静态类
  1. 接着检查tag(若有传入)是否和fragment已有保存的不同,最后保存在fragment中
  2. 接着检查布局ID(若有传入),该布局为FragmentActivity中用于承载fragment的ViewGroup,必须有设置ID,fragment中若已有设置必须相同,最后fragment保存容器ID,mFragmentId默认也为容器ID
  3. 封装Op保存操作类型和fragment,并添加至操作集合
Op

Op表示一个操作,看它的构造函数:

[FragmentTransaction.java]

Op(int cmd, Fragment fragment) {
    // 保存操作类型
    this.mCmd = cmd;
    // 保存待操作的fragment
    this.mFragment = fragment;
    // 生命周期状态置为RESUMED,对应Activity执行onResume之后的状态
    this.mOldMaxState = Lifecycle.State.RESUMED;
    this.mCurrentMaxState = Lifecycle.State.RESUMED;
}
addOp

[FragmentTransaction.java]

void addOp(Op op) {
    // 保存Op对象
    mOps.add(op);
    // 动画相关,默认都为0
    op.mEnterAnim = mEnterAnim;
    op.mExitAnim = mExitAnim;
    op.mPopEnterAnim = mPopEnterAnim;
    op.mPopExitAnim = mPopExitAnim;
}

FragmentTransaction的mOps成员用于保存Op对象,mOps为ArrayList。

提交事务

FragmentTransaction有四个提交事务的方法:commit、commitAllowingStateLoss、commitNow、commitNowAllowingStateLoss。这四个方法都为抽象类,具体实现在BackStackRecord中。

这里以commitAllowingStateLoss为例: [BackStackRecord.java]

public int commitAllowingStateLoss() {
    return commitInternal(true);
}

int commitInternal(boolean allowStateLoss) {
    if (mCommitted) throw new IllegalStateException("commit already called");
    // 省略DEBUG部分 ···
    mCommitted = true;
    // mAddToBackStack默认为false,若调用addToBackStack方法的话为true
    if (mAddToBackStack) {
        mIndex = mManager.allocBackStackIndex(this);
    } else {
        mIndex = -1;
    }
    // 此时传入的allowStateLoss为true
    // 通过FragmentManagerImpl入队
    mManager.enqueueAction(this, allowStateLoss);
    return mIndex;
}

接着看FragmentManagerImpl的enqueueAction方法,此时传入BackStackRecord自身和true: [FragmentManagerImpl.java]

public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
    if (!allowStateLoss) {
        checkStateLoss();
    }
    synchronized (this) {
        if (mDestroyed || mHost == null) {
            if (allowStateLoss) {
                // This FragmentManager isn't attached, so drop the entire transaction.
                return;
            }
            throw new IllegalStateException("Activity has been destroyed");
        }
        if (mPendingActions == null) {
            mPendingActions = new ArrayList<>();
        }
        // mPendingActions表示待执行操作集合,action即为BackStackRecord(实现了OpGenerator接口)
        mPendingActions.add(action);
        scheduleCommit();
    }
}

接着看scheduleCommit方法: [FragmentManagerImpl.java]

void scheduleCommit() {
    synchronized (this) {
        // 标记是否存在延迟事务,默认不存在
        boolean postponeReady =
                mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
        // 标记是否仅存在一个待执行事务,第一次通过enqueueAction提交事务时符合条件
        boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
        if (postponeReady || pendingReady) {
            // 符合条件,通过Handler调度任务执行
            mHost.getHandler().removeCallbacks(mExecCommit);
            mHost.getHandler().post(mExecCommit);
            updateOnBackPressedCallbackEnabled();
        }
    }
}

当存在延迟事务或第一次提交事务时,会通过Handler来post一个Runnable执行操作,这里的Handler即HostCallbacks实例化时创建的主线程Handler。

可见通过commit、commitAllowingStateLoss方法提交的事务不会立即执行,而是等待主线程LOOPER下一次取出消息时执行。

处理事务操作

前文中使用Handler post的mExecCommit是一个Runnable: [FragmentManagerImpl.java]

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

触发时将调用execPendingActions方法处理事务操作: [FragmentManagerImpl.java]

public boolean execPendingActions() {
    // 检查状态和初始化mTmpRecords、mTmpIsPop集合和处理延迟事务
    ensureExecReady(true);

    boolean didSomething = false;
    // 生成命令并保存在mTmpRecords、mTmpIsPop集合中
    while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
        // 标记当前处于执行事务中
        mExecutingActions = true;
        try {
            // 移除或合并多余的操作并执行
            removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
        } finally {
            cleanupExec();
        }
        didSomething = true;
    }

    updateOnBackPressedCallbackEnabled();
    // 执行推迟启动的Fragment
    doPendingDeferredStart();
    // 清理mActive集合
    burpActive();

    return didSomething;
}

该方法中会在一个while循环中检索待执行事务并执行,当generateOpsForPendingActions返回false表示没有待执行的事务,则结束while循环。

两个集合的说明:

  • mTmpRecords:保存待执行的BackStackRecord。
  • mTmpIsPop:标记与mTmpRecords对应索引的BackStackRecord是添加类型还是移除类型的,默认为false,通过popBackStack回退时,会标记对应索引位置为true。

generateOpsForPendingActions

[FragmentManagerImpl.java]

private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records,
                                             ArrayList<Boolean> isPop) {
    // 标记是否有执行事务
    boolean didSomething = false;
    synchronized (this) {
        // 若不存在待执行事务则返回false
        if (mPendingActions == null || mPendingActions.size() == 0) {
            return false;
        }

        final int numActions = mPendingActions.size();
        // 遍历mPendingActions,此时仅有一个OP_ADD类型的BackStackRecord
        for (int i = 0; i < numActions; i++) {
            // 依次调用generateOps方法
            didSomething |= mPendingActions.get(i).generateOps(records, isPop);
        }
        // 清空mPendingActions
        mPendingActions.clear();
        // 移除mExecCommit,避免冗余执行
        mHost.getHandler().removeCallbacks(mExecCommit);
    }
    return didSomething;
}

generateOps

这里以添加Fragment为例,此时mPendingActions中存在一个OP_ADD类型的BackStackRecord,查看它的generateOps方法: [BackStackRecord.java]

public boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop) {
    if (FragmentManagerImpl.DEBUG) {
        Log.v(TAG, "Run: " + this);
    }

    // records集合添加BackStackRecord自身
    records.add(this);
    // isRecordPop添加false
    isRecordPop.add(false);
    // mAddToBackStack默认为false,因此不加入回退栈
    if (mAddToBackStack) {
        mManager.addBackStackState(this);
    }
    return true;
}

removeRedundantOperationsAndExecute

[FragmentManagerImpl.java]

private void removeRedundantOperationsAndExecute(ArrayList<BackStackRecord> records,
                                                 ArrayList<Boolean> isRecordPop) {
    if (records == null || records.isEmpty()) {
        return;
    }

    if (isRecordPop == null || records.size() != isRecordPop.size()) {
        throw new IllegalStateException("Internal error with the back stack records");
    }

    // Force start of any postponed transactions that interact with scheduled transactions:
    executePostponedTransaction(records, isRecordPop);

    final int numRecords = records.size();
    int startIndex = 0;
    for (int recordNum = 0; recordNum < numRecords; recordNum++) {
        // 标记是否支持操作排序优化,默认为false
        final boolean canReorder = records.get(recordNum).mReorderingAllowed;
        if (!canReorder) {
            // execute all previous transactions
            if (startIndex != recordNum) {
                executeOpsTogether(records, isRecordPop, startIndex, recordNum);
            }
            // execute all pop operations that don't allow reordering together or
            // one add operation
            int reorderingEnd = recordNum + 1;
            // 非pop事务都返回false
            if (isRecordPop.get(recordNum)) {
                while (reorderingEnd < numRecords
                        && isRecordPop.get(reorderingEnd)
                        && !records.get(reorderingEnd).mReorderingAllowed) {
                    reorderingEnd++;
                }
            }
            // 执行指定索引区间中的BackStackRecord
            executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
            startIndex = reorderingEnd;
            recordNum = reorderingEnd - 1;
        }
    }
    if (startIndex != numRecords) {
        // 开启操作排序优化情况下可能会满足该if条件
        executeOpsTogether(records, isRecordPop, startIndex, numRecords);
    }
}
操作排序优化

当有多个待执行事务时,FragmentManager会删除部分冗余事务操作。例如:

  • 假设有两个事务对同一布局容器一起执行,一个事务添加了一个 Fragment A,下一个事务将其替换为 Fragment B。则优化后会将第一个操作取消,仅添加 Fragment B。
  • 假设有三个事务,一个事务添加了 Fragment A,第二个事务添加了 Fragment B,然后第三个删除了 Fragment A。那么优化后将不会执行 Fragment A的添加和删除,仅添加 Fragment B。

排序优化操作会导致出现超出开发者预期的行为,因此默认不进行此操作。

executeOpsTogether

进入executeOpsTogether方法: [FragmentManagerImpl.java]

private void executeOpsTogether(ArrayList<BackStackRecord> records,
                                ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
    // ···
    executeOps(records, isRecordPop, startIndex, endIndex);
    // ···
}

进入executeOps方法: [FragmentManagerImpl.java]

private static void executeOps(ArrayList<BackStackRecord> records,
                               ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
    for (int i = startIndex; i < endIndex; i++) {
        final BackStackRecord record = records.get(i);
        final boolean isPop = isRecordPop.get(i);
        if (isPop) {
            record.bumpBackStackNesting(-1);
            // Only execute the add operations at the end of
            // all transactions.
            boolean moveToState = i == (endIndex - 1);
            // 执行回退操作
            record.executePopOps(moveToState);
        } else {
            record.bumpBackStackNesting(1);
            // OP_ADD类型执行executeOps
            record.executeOps();
        }
    }
}

executeOps

看BackStackRecord的executeOps方法中的OP_ADD case: [BackStackRecord.java]

void executeOps() {
    final int numOps = mOps.size();
    // 遍历该事务中的操作
    for (int opNum = 0; opNum < numOps; opNum++) {
        final Op op = mOps.get(opNum);
        final Fragment f = op.mFragment;
        if (f != null) {
            f.setNextTransition(mTransition, mTransitionStyle);
        }
        switch (op.mCmd) {
            case OP_ADD:
                f.setNextAnim(op.mEnterAnim);
                // 添加Fragment
                mManager.addFragment(f, false);
                break;
            // 省略其他case ···
            default:
                throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
        }
        if (!mReorderingAllowed && op.mCmd != OP_ADD && f != null) {
            mManager.moveFragmentToExpectedState(f);
        }
    }
    // mReorderingAllowed默认为false
    if (!mReorderingAllowed) {
        // Added fragments are added at the end to comply with prior behavior.
        // 更新状态,这里传入FragmentManagerImpl的当前状态和true
        mManager.moveToState(mManager.mCurState, true);
    }
}

该方法中处理OP_ADD时,首先通过addFragment方法添加fragment至集合中保存,最后通过moveToState更新状态并设置fragment。

addFragment

[FragmentManagerImpl.java]

public void addFragment(Fragment fragment, boolean moveToStateNow) {
    if (DEBUG) Log.v(TAG, "add: " + fragment);
    // 将fragment添加至mActive集合保存,若设置setRetainInstance还将添加入FragmentManagerViewModel中保存
    makeActive(fragment);
    // 此时为OP_ADD操作,mDetached为false
    if (!fragment.mDetached) {
        if (mAdded.contains(fragment)) {
            throw new IllegalStateException("Fragment already added: " + fragment);
        }
        synchronized (mAdded) {
            // fragment加入mAdded集合
            mAdded.add(fragment);
        }
        // mAdded用于标记该fragment是否已经加入mAdded集合
        fragment.mAdded = true;
        // mRemoving标记该fragment是否从Activity移除
        fragment.mRemoving = false;
        // 此时mView还未生成,为null
        if (fragment.mView == null) {
            fragment.mHiddenChanged = false;
        }
        if (isMenuAvailable(fragment)) {
            mNeedMenuInvalidate = true;
        }
        // 此时传入的moveToStateNow为false
        if (moveToStateNow) {
            moveToState(fragment);
        }
    }
}

将fragment添加入mActive和mAdded集合中。

moveToState

回到BackStackRecord.executeOps方法中,在方法的最后执行moveToState方法:

[FragmentManagerImpl.java]

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

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

    // 更新状态,此时传入的newState和mCurState相等
    mCurState = newState;

    // Must add them in the proper order. mActive fragments may be out of order
    final int numAdded = mAdded.size();
    // 遍历mAdded,依次取出Fragment处理
    for (int i = 0; i < numAdded; i++) {
        Fragment f = mAdded.get(i);
        moveFragmentToExpectedState(f);
    }

    // 省略···
}

该方法中依次取出Fragment,调用moveFragmentToExpectedState将Fragment根据最终期望的状态进行初始化设置。

mCurState成员记录FragmentManagerImpl的当前状态,状态值有:

  • INITIALIZING(0):初始状态,默认状态
  • CREATED(1):初创状态,对应onCreate、onDestroyView阶段
  • ACTIVITY_CREATED(2):created以上、started未满状态,对应onStart、onStop阶段
  • STARTED(3):started以上、resumed未满阶段,对应onResume、onPause阶段
  • RESUMED(4):resumed以上状态,对应onResume完成阶段

看moveFragmentToExpectedState方法: [FragmentManagerImpl.java]

void moveFragmentToExpectedState(Fragment f) {
    if (f == null) {
        return;
    }
    if (!mActive.containsKey(f.mWho)) {
        if (DEBUG) {
            Log.v(TAG, "Ignoring moving " + f + " to state " + mCurState
                    + "since it is not added to " + this);
        }
        return;
    }
    int nextState = mCurState;
    if (f.mRemoving) {
        if (f.isInBackStack()) {
            nextState = Math.min(nextState, Fragment.CREATED);
        } else {
            nextState = Math.min(nextState, Fragment.INITIALIZING);
        }
    }
    // 调度fragment到目标状态对应阶段,并执行对应阶段的初始化设置
    moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);

    if (f.mView != null) {
        // ···
    }
    if (f.mHiddenChanged) {
        completeShowHideFragment(f);
    }
}

该方法中调用另一个moveToState重载方法: [FragmentManagerImpl.java]

void moveToState(Fragment f, int newState, int transit, int transitionStyle,
                 boolean keepActive) {
    // 省略状态检查校验部分
    // ···
    
    // 判断fragment的生命周期状态是否小等于FragmentManager的状态,刚创建添加的fragment状态默认为INITIALIZING
    if (f.mState <= newState) {
        // ···
        switch (f.mState) {
            case Fragment.INITIALIZING:
                // 开始进入attach阶段
                if (newState > Fragment.INITIALIZING) {
                    if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
                    // 省略mSavedFragmentState部分 ···

                    f.mHost = mHost;
                    f.mParentFragment = mParent;
                    f.mFragmentManager = mParent != null
                            ? mParent.mChildFragmentManager : mHost.mFragmentManager;

                    // If we have a target fragment, push it along to at least CREATED
                    // so that this one can rely on it as an initialized dependency.
                    // 省略mTarget部分 ···
                    // 省略mTargetWho部分 ···

                    dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
                    f.performAttach();
                    if (f.mParentFragment == null) {
                        mHost.onAttachFragment(f);
                    } else {
                        f.mParentFragment.onAttachFragment(f);
                    }
                    dispatchOnFragmentAttached(f, mHost.getContext(), false);

                    if (!f.mIsCreated) {
                        dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
                        f.performCreate(f.mSavedFragmentState);
                        dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
                    } else {
                        f.restoreChildFragmentState(f.mSavedFragmentState);
                        f.mState = Fragment.CREATED;
                    }
                }
                // fall through
                // 注意此处无break,会继续往下匹配case执行
            case Fragment.CREATED:
                // 开始进入CreateView阶段
                // We want to unconditionally run this anytime we do a moveToState that
                // moves the Fragment above INITIALIZING, including cases such as when
                // we move from CREATED => CREATED as part of the case fall through above.
                if (newState > Fragment.INITIALIZING) {
                    ensureInflatedFragmentView(f);
                }

                if (newState > Fragment.CREATED) {
                    if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
                    if (!f.mFromLayout) {
                        ViewGroup container = null;
                        if (f.mContainerId != 0) {
                            if (f.mContainerId == View.NO_ID) {
                                throwException(new IllegalArgumentException(
                                        "Cannot create fragment "
                                                + f
                                                + " for a container view with no id"));
                            }
                            // 获取布局容器,通过FragmentActivity.this.findViewById(f.mContainerId)获取
                            container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
                            if (container == null && !f.mRestored) {
                                String resName;
                                try {
                                    resName = f.getResources().getResourceName(f.mContainerId);
                                } catch (Resources.NotFoundException e) {
                                    resName = "unknown";
                                }
                                throwException(new IllegalArgumentException(
                                        "No view found for id 0x"
                                                + Integer.toHexString(f.mContainerId) + " ("
                                                + resName
                                                + ") for fragment " + f));
                            }
                        }
                        f.mContainer = container;
                        // performGetLayoutInflater中通过FragmentActivity上下文获取LayoutInflater
                        // performCreateView中会触发fragment的onCreateView方法,
                        // 返回我们自定义的视图,并赋值给mView成员
                        f.performCreateView(f.performGetLayoutInflater(
                                f.mSavedFragmentState), container, f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.mInnerView = f.mView;
                            f.mView.setSaveFromParentEnabled(false);
                            if (container != null) {
                                // 将fragment的view加入布局容器中
                                container.addView(f.mView);
                            }
                            if (f.mHidden) {
                                f.mView.setVisibility(View.GONE);
                            }
                            f.onViewCreated(f.mView, f.mSavedFragmentState);
                            dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
                                    false);
                            // Only animate the view if it is visible. This is done after
                            // dispatchOnFragmentViewCreated in case visibility is changed
                            f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
                                    && f.mContainer != null;
                        } else {
                            f.mInnerView = null;
                        }
                    }

                    f.performActivityCreated(f.mSavedFragmentState);
                    dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
                    if (f.mView != null) {
                        f.restoreViewState(f.mSavedFragmentState);
                    }
                    f.mSavedFragmentState = null;
                }
                // fall through
            case Fragment.ACTIVITY_CREATED:
                if (newState > Fragment.ACTIVITY_CREATED) {
                    if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
                    f.performStart();
                    dispatchOnFragmentStarted(f, false);
                }
                // fall through
            case Fragment.STARTED:
                if (newState > Fragment.STARTED) {
                    if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
                    f.performResume();
                    dispatchOnFragmentResumed(f, false);
                    f.mSavedFragmentState = null;
                    f.mSavedViewState = null;
                }
        }
    } else if (f.mState > newState) {
        // 省略生命周期逆生长部分,即onPause、onStop、onDestroyView、onDestroy、onDetach
        // ···
    }
    
    if (f.mState != newState) {
        Log.w(TAG, "moveToState: Fragment state for " + f + " not updated inline; "
                + "expected state " + newState + " found " + f.mState);
        // 更新fragment的状态
        f.mState = newState;
    }
}

moveToState方法中在CREATED状态阶段,完成了Fragment视图的创建(若有自定义视图),接着添加至给定的布局容器中。

moveToState方法还会根据Fragment和FragmentManager当前的生命周期状态,调度Fragment的状态更新,在其中还会触发Fragment各阶段的生命周期回调方法。

REMOVE操作类型

通过调用BackStackRecord的remove方法,传入指定Fragment,达到移除Fragment的作用。

[BackStackRecord.java]

public FragmentTransaction remove(@NonNull Fragment fragment) {
    if (fragment.mFragmentManager != null && fragment.mFragmentManager != mManager) {
        throw new IllegalStateException("Cannot remove Fragment attached to "
                + "a different FragmentManager. Fragment " + fragment.toString() + " is already"
                + " attached to a FragmentManager.");
    }
    return super.remove(fragment);
}

调用父类FragmentTransaction的remove方法: [FragmentTransaction.java]

public FragmentTransaction remove(@NonNull Fragment fragment) {
    addOp(new Op(OP_REMOVE, fragment));

    return this;
}

remove方法中创建Op对象,传入命令类型OP_REMOVE和要移除的fragment,添加到命令集合mOps成员中。

接下来的步骤就是提交事务,加入事务队列,等待调度执行,同OP_ADD一样,将会执行BackStackRecord的executeOps方法: [BackStackRecord.java]

void executeOps() {
    for (int opNum = 0; opNum < numOps; opNum++) {
        final Op op = mOps.get(opNum);
        final Fragment f = op.mFragment;
        if (f != null) {
            f.setNextTransition(mTransition, mTransitionStyle);
        }
        switch (op.mCmd) {
            // ···
            case OP_REMOVE:
                f.setNextAnim(op.mExitAnim);
                // 将该fragment从FragmentManagerImpl的mAdded成员中移除,并设置
                // 该fragment的mAdded成员为false、mRemoving成员为true
                mManager.removeFragment(f);
                break;
            // ···
        }
        // mReorderingAllowed默认为false
        if (!mReorderingAllowed && op.mCmd != OP_ADD && f != null) {
            // 更新fragment的生命状态和执行对应阶段的生命周期回调和释放销毁
            mManager.moveFragmentToExpectedState(f);
        }
    }
    if (!mReorderingAllowed) {
        // Added fragments are added at the end to comply with prior behavior.
        // 更新当前FragmentManagerImpl中管理的Fragment的状态
        mManager.moveToState(mManager.mCurState, true);
    }
}

moveFragmentToExpectedState和moveToState方法在处理OP_ADD命令时见到过,是通用方法,其他命令也都会调用这两个方法。

[FragmentManagerImpl.java]

void moveFragmentToExpectedState(Fragment f) {
    // ···
    int nextState = mCurState;
    // mRemoving此时已经置为true
    if (f.mRemoving) {
        // 修改要更新至的目标状态,若该fragment不为最后一个,则目标状态为CREATED
        if (f.isInBackStack()) {
            nextState = Math.min(nextState, Fragment.CREATED);
        } else {
            nextState = Math.min(nextState, Fragment.INITIALIZING);
        }
    }
    // 调度fragment到目标状态对应阶段,并执行对应阶段的处理
    moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
    // ···
}

[FragmentManagerImpl.java]

void moveToState(Fragment f, int newState, int transit, int transitionStyle,
                 boolean keepActive) {
    // ···
    if (f.mState <= newState) {
        // ···
    } else if (f.mState > newState) {
        switch (f.mState) {
            case Fragment.RESUMED:
                // ···
            case Fragment.STARTED:
                // ···
            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 (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
                            saveFragmentViewState(f);
                        }
                    }
                    f.performDestroyView();
                    dispatchOnFragmentViewDestroyed(f, false);
                    if (f.mView != null && f.mContainer != null) {
                        // Stop any current animations:
                        f.mContainer.endViewTransition(f.mView);
                        f.mView.clearAnimation();
                        AnimationOrAnimator anim = null;
                        // If parent is being removed, no need to handle child animations.
                        if (f.getParentFragment() == null || !f.getParentFragment().mRemoving) {
                            if (mCurState > Fragment.INITIALIZING && !mDestroyed
                                    && f.mView.getVisibility() == View.VISIBLE
                                    && f.mPostponedAlpha >= 0) {
                                anim = loadAnimation(f, transit, false,
                                        transitionStyle);
                            }
                            f.mPostponedAlpha = 0;
                            if (anim != null) {
                                animateRemoveFragment(f, anim, newState);
                            }
                            // 设置了view和布局容器的情况下,需要从布局中移除该Fragment的view
                            f.mContainer.removeView(f.mView);
                        }
                    }
                    // 解除引用
                    f.mContainer = null;
                    f.mView = null;
                    // Set here to ensure that Observers are called after
                    // the Fragment's view is set to null
                    f.mViewLifecycleOwner = null;
                    f.mViewLifecycleOwnerLiveData.setValue(null);
                    f.mInnerView = null;
                    f.mInLayout = false;
                }
                // fall through
            case Fragment.CREATED:
                if (newState < Fragment.CREATED) {
                    if (mDestroyed) {
                        // 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.
                        if (f.getAnimatingAway() != null) {
                            View v = f.getAnimatingAway();
                            f.setAnimatingAway(null);
                            v.clearAnimation();
                        } else if (f.getAnimator() != null) {
                            Animator animator = f.getAnimator();
                            f.setAnimator(null);
                            animator.cancel();
                        }
                    }
                    if (f.getAnimatingAway() != null || f.getAnimator() != 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.setStateAfterAnimating(newState);
                        newState = Fragment.CREATED;
                    } else {
                        if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
                        boolean beingRemoved = f.mRemoving && !f.isInBackStack();
                        if (beingRemoved || mNonConfig.shouldDestroy(f)) {
                            boolean shouldClear;
                            if (mHost instanceof ViewModelStoreOwner) {
                                shouldClear = mNonConfig.isCleared();
                            } else if (mHost.getContext() instanceof Activity) {
                                Activity activity = (Activity) mHost.getContext();
                                shouldClear = !activity.isChangingConfigurations();
                            } else {
                                shouldClear = true;
                            }
                            if (beingRemoved || shouldClear) {
                                mNonConfig.clearNonConfigState(f);
                            }
                            f.performDestroy();
                            dispatchOnFragmentDestroyed(f, false);
                        } else {
                            f.mState = Fragment.INITIALIZING;
                        }

                        f.performDetach();
                        dispatchOnFragmentDetached(f, false);
                        if (!keepActive) {
                            if (beingRemoved || mNonConfig.shouldDestroy(f)) {
                                makeInactive(f);
                            } else {
                                f.mHost = null;
                                f.mParentFragment = null;
                                f.mFragmentManager = null;
                                if (f.mTargetWho != null) {
                                    Fragment target = mActive.get(f.mTargetWho);
                                    if (target != null && target.getRetainInstance()) {
                                        // Only keep references to other retained Fragments
                                        // to avoid developers accessing Fragments that
                                        // are never coming back
                                        f.mTarget = target;
                                    }
                                }
                            }
                        }
                    }
                }
        }
    }
    
    if (f.mState != newState) {
        Log.w(TAG, "moveToState: Fragment state for " + f + " not updated inline; "
        + "expected state " + newState + " found " + f.mState);
        f.mState = newState;
    }
}

OP_REMOVE操作会把指定的fragment从FragmentManagerImpl中移除,移除过程中会视配置情况进行状态保存、移除view、释放fragment、FragmentManagerImpl调度其他fragment等处理。

REPLACE操作类型

通过调用FragmentTransaction的replace方法,传入指定的布局容器ID和fragment,达到替换布局容器中的fragment的view。

[FragmentTransaction.java]

public FragmentTransaction replace(@IdRes int containerViewId, @NonNull Fragment fragment,
        @Nullable String tag)  {
    // 必须指定布局容器ID
    if (containerViewId == 0) {
        throw new IllegalArgumentException("Must use non-zero containerViewId");
    }
    doAddOp(containerViewId, fragment, tag, OP_REPLACE);
    return this;
}

添加OP_REPLACE类型的Op到mOps集合中。

接着看执行命令操作的方法executeOpsTogether: [FragmentManagerImpl.java]

private void executeOpsTogether(ArrayList<BackStackRecord> records,
                                ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
    // ···
    for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
        final BackStackRecord record = records.get(recordNum);
        final boolean isPop = isRecordPop.get(recordNum);
        if (!isPop) {
            // 根据操作类型进行展开操作
            oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
        } else {
            oldPrimaryNav = record.trackAddedFragmentsInPop(mTmpAddedFragments, oldPrimaryNav);
        }
        addToBackStack = addToBackStack || record.mAddToBackStack;
    }
    // ···
    // 执行操作
    executeOps(records, isRecordPop, startIndex, endIndex);
    // ···
}

该方法中再执行命令操作前会先调用BackStackRecord的expandOps方法中根据操作类型进行展开操作。

[BackStackRecord.java]

Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
    // 遍历mOps集合中的Op
    for (int opNum = 0; opNum < mOps.size(); opNum++) {
        final Op op = mOps.get(opNum);
        switch (op.mCmd) {
            case OP_ADD:
            case OP_ATTACH:
                added.add(op.mFragment);
                break;
            case OP_REMOVE:
            case OP_DETACH: {
                added.remove(op.mFragment);
                if (op.mFragment == oldPrimaryNav) {
                    mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.mFragment));
                    opNum++;
                    oldPrimaryNav = null;
                }
            }
            break;
            case OP_REPLACE: {
                final Fragment f = op.mFragment;
                final int containerId = f.mContainerId;
                // 标记该fragment是否添加过
                boolean alreadyAdded = false;
                // 遍历FragmentManagerImpl的mAdded中的Fragment
                for (int i = added.size() - 1; i >= 0; i--) {
                    final Fragment old = added.get(i);
                    // 判断是否指定过相同的布局容器ID
                    if (old.mContainerId == containerId) {
                        // 判断指定了相同布局容器的那个fragment是否就是这个fragment
                        if (old == f) {
                            // 标记为true
                            alreadyAdded = true;
                        } else {
                            // This is duplicated from above since we only make
                            // a single pass for expanding ops. Unset any outgoing primary nav.
                            if (old == oldPrimaryNav) {
                                mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, old));
                                opNum++;
                                oldPrimaryNav = null;
                            }
                            // 创建OP_REMOVE的操作
                            final Op removeOp = new Op(OP_REMOVE, old);
                            removeOp.mEnterAnim = op.mEnterAnim;
                            removeOp.mPopEnterAnim = op.mPopEnterAnim;
                            removeOp.mExitAnim = op.mExitAnim;
                            removeOp.mPopExitAnim = op.mPopExitAnim;
                            // 添加进mOps中
                            mOps.add(opNum, removeOp);
                            // 移除指定的布局容器中的那个fragment
                            added.remove(old);
                            opNum++;
                        }
                    }
                }
                if (alreadyAdded) {
                    // 若该fragment已经添加了,移除这个操作即可
                    mOps.remove(opNum);
                    opNum--;
                } else {
                    // 将这个操作的类型修改成OP_ADD
                    op.mCmd = OP_ADD;
                    // 将fragment添加进mAdded中
                    added.add(f);
                }
            }
            break;
            case OP_SET_PRIMARY_NAV: {
                // ···
            }
            break;
        }
    }
    return oldPrimaryNav;
}

可以看到OP_REPLACE操作其实是调整为OP_REMOVE+OP_ADD。

HIDE和SHOW操作类型

通过FragmentTransaction的hide和show方法,可以将指定的fragment隐藏和显示。 [FragmentTransaction.java]

public FragmentTransaction hide(@NonNull Fragment fragment) {
    addOp(new Op(OP_HIDE, fragment));

    return this;
}

public FragmentTransaction show(@NonNull Fragment fragment) {
    addOp(new Op(OP_SHOW, fragment));

    return this;
}

添加OP_HIDEOP_SHOW类型的命令。

接着看处理的部分,在executeOps方法的OP_HIDE case和OP_SHOW case中,会调用FragmentManagerImpl的hideFragment和showFragment方法: [FragmentManagerImpl.java]

public void hideFragment(Fragment fragment) {
    if (DEBUG) Log.v(TAG, "hide: " + fragment);
    if (!fragment.mHidden) {
        // 将mHidden成员标记为true
        fragment.mHidden = true;
        // Toggle hidden changed so that if a fragment goes through show/hide/show
        // it doesn't go through the animation.
        fragment.mHiddenChanged = !fragment.mHiddenChanged;
    }
}

public void showFragment(Fragment fragment) {
    if (DEBUG) Log.v(TAG, "show: " + fragment);
    if (fragment.mHidden) {
        // 将mHidden成员标记为false
        fragment.mHidden = false;
        // Toggle hidden changed so that if a fragment goes through show/hide/show
        // it doesn't go through the animation.
        fragment.mHiddenChanged = !fragment.mHiddenChanged;
    }
}

Fragment中是通过mHidden成员来标记当前是要隐藏还是要显示。

接下来在FragmentManagerImpl的moveToState方法中,会根据mHidden值来设置view的可见: [FragmentManagerImpl.java]

void moveToState(Fragment f, int newState, int transit, int transitionStyle,
                 boolean keepActive) {
    // ···
    if (f.mState <= newState) {
        // ···
        switch (f.mState) {
            // ···
            case Fragment.CREATED:
                // We want to unconditionally run this anytime we do a moveToState that
                // moves the Fragment above INITIALIZING, including cases such as when
                // we move from CREATED => CREATED as part of the case fall through above.
                if (newState > Fragment.INITIALIZING) {
                    // 该处理从xml文件中添加Fragment
                    ensureInflatedFragmentView(f);
                }

                if (newState > Fragment.CREATED) {
                    if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
                    if (!f.mFromLayout) {
                        ViewGroup container = null;
                        if (f.mContainerId != 0) {
                            if (f.mContainerId == View.NO_ID) {
                                throwException(new IllegalArgumentException(
                                        "Cannot create fragment "
                                                + f
                                                + " for a container view with no id"));
                            }
                            container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
                            if (container == null && !f.mRestored) {
                                String resName;
                                try {
                                    resName = f.getResources().getResourceName(f.mContainerId);
                                } catch (Resources.NotFoundException e) {
                                    resName = "unknown";
                                }
                                throwException(new IllegalArgumentException(
                                        "No view found for id 0x"
                                                + Integer.toHexString(f.mContainerId) + " ("
                                                + resName
                                                + ") for fragment " + f));
                            }
                        }
                        f.mContainer = container;
                        f.performCreateView(f.performGetLayoutInflater(
                                f.mSavedFragmentState), container, f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.mInnerView = f.mView;
                            f.mView.setSaveFromParentEnabled(false);
                            if (container != null) {
                                container.addView(f.mView);
                            }
                            // 在创建完view后,判断mHidden是否为true
                            if (f.mHidden) {
                                // 设置view为GONE
                                f.mView.setVisibility(View.GONE);
                            }
                            f.onViewCreated(f.mView, f.mSavedFragmentState);
                            dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
                                    false);
                            // Only animate the view if it is visible. This is done after
                            // dispatchOnFragmentViewCreated in case visibility is changed
                            f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
                                    && f.mContainer != null;
                        } else {
                            f.mInnerView = null;
                        }
                    }

                    f.performActivityCreated(f.mSavedFragmentState);
                    dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
                    if (f.mView != null) {
                        f.restoreViewState(f.mSavedFragmentState);
                    }
                    f.mSavedFragmentState = null;
                }
            // ···
        }
    } else if (f.mState > newState) {
        // ···
    }
    // ···
}

void ensureInflatedFragmentView(Fragment f) {
    if (f.mFromLayout && !f.mPerformedCreateView) {
        f.performCreateView(f.performGetLayoutInflater(
                f.mSavedFragmentState), null, f.mSavedFragmentState);
        if (f.mView != null) {
            f.mInnerView = f.mView;
            f.mView.setSaveFromParentEnabled(false);
            // 若mHidden为true,则将view设置为GONE
            if (f.mHidden) f.mView.setVisibility(View.GONE);
            f.onViewCreated(f.mView, f.mSavedFragmentState);
            dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
        } else {
            f.mInnerView = null;
        }
    }
}

若mHidden设置为true,则会将通过Fragment创建的view的可见属性设置为GONE。

回到FragmentManagerImpl的moveFragmentToExpectedState方法: [FragmentManagerImpl.java]

void moveFragmentToExpectedState(Fragment f) {
    // ···
    moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
    // ···
    // mHiddenChanged默认为false,当对fragment进行显示隐藏操作变化时会变为true
    if (f.mHiddenChanged) {
        completeShowHideFragment(f);
    }
}

该方法中在执行完moveToState方法将fragment调整到最终目标状态后,在该方法的结尾会判断调用completeShowHideFragment方法,进入这个方法看看做了什么动作: [FragmentManagerImpl.java]

void completeShowHideFragment(final Fragment fragment) {
    // 判断该fragment中是否有创建view
    if (fragment.mView != null) {
        AnimationOrAnimator anim = loadAnimation(fragment, fragment.getNextTransition(),
                !fragment.mHidden, fragment.getNextTransitionStyle());
        // 判断是否设置了Animator
        if (anim != null && anim.animator != null) {
            anim.animator.setTarget(fragment.mView);
            // 判断该fragment是否隐藏
            if (fragment.mHidden) {
                // isHideReplaced方法判断是否正在进行隐藏的过渡动画中
                if (fragment.isHideReplaced()) {
                    // 正在进行隐藏的过渡动画
                    fragment.setHideReplaced(false);
                } else {
                    // 设置进行隐藏的过渡动画
                    final ViewGroup container = fragment.mContainer;
                    final View animatingView = fragment.mView;
                    container.startViewTransition(animatingView);
                    // Delay the actual hide operation until the animation finishes,
                    // otherwise the fragment will just immediately disappear
                    anim.animator.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            container.endViewTransition(animatingView);
                            animation.removeListener(this);
                            if (fragment.mView != null && fragment.mHidden) {
                                fragment.mView.setVisibility(View.GONE);
                            }
                        }
                    });
                }
            } else {
                // 若为显示,则将fragment的view设置为VISIBLE
                fragment.mView.setVisibility(View.VISIBLE);
            }
            anim.animator.start();
        } else {
            if (anim != null) {
                // 未设置Animator,但设置了Animation
                fragment.mView.startAnimation(anim.animation);
                anim.animation.start();
            }
            final int visibility = fragment.mHidden && !fragment.isHideReplaced()
                    ? View.GONE
                    : View.VISIBLE;
            // 设置fragment的view的可见属性
            fragment.mView.setVisibility(visibility);
            if (fragment.isHideReplaced()) {
                fragment.setHideReplaced(false);
            }
        }
    }
    if (fragment.mAdded && isMenuAvailable(fragment)) {
        mNeedMenuInvalidate = true;
    }
    // 把mHiddenChanged成员置回false
    fragment.mHiddenChanged = false;
    // 回调onHiddenChanged方法
    fragment.onHiddenChanged(fragment.mHidden);
}

该方法中逻辑主要是过渡动画和view可见属性的设置。

总结

前文大致跟踪了一个Fragment从新建到添加入FragmentActivity的过程。 首先FragmentManager将“添加Fragment”的行为封装成一个Op操作,再将Op加入一个事务BackStackRecord,然后将事务加入待执行队列保存,之后通过Handler调度至主线程执行。 接着FragmentManager从遍历待执行队列中的事务,依次执行。执行过程中根据操作类型以及Fragment状态和FragmentManager状态,执行Fragment对应阶段的处理和生命周期回调。