Android Fragment beginTransaction

Android Fragment beginTransaction

通过下面的示例代码进行详细的分析.
fm : android.app.FragmentManager
current : RequestManagerFragment
FRAGMENT_TAG : “com.bumptech.glide.manager”

	fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();

1. fm.beginTransaction() 开始事务 拿到FragmentTransaction对象进行下一步的操作

当前方法直接追寻只能看到是一个抽象的方法,所以我们需要找到具体在什么地方进行实现的.

    /**
     * Start a series of edit operations on the Fragments associated with
     * this FragmentManager.
     * 
     * <p>Note: A fragment transaction can only be created/committed prior
     * to an activity saving its state.  If you try to commit a transaction
     * after {@link Activity#onSaveInstanceState Activity.onSaveInstanceState()}
     * (and prior to a following {@link Activity#onStart Activity.onStart}
     * or {@link Activity#onResume Activity.onResume()}, you will get an error.
     * This is because the framework takes care of saving your current fragments
     * in the state, and if changes are made after the state is saved then they
     * will be lost.</p>
     */
    public abstract FragmentTransaction beginTransaction();

根据当前类的查找我们发现只有一个类进行当前类的实现或者继承.
在这里插入图片描述
所以FragmentManager->beginTransaction方法的实现在FragmentManagerImpl中,不过两个类在同一个java文件中

    @Override
    public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this); // 直接创建了一个BackStackRecord对象返回
    }
BackStackRecord
    public BackStackRecord(FragmentManagerImpl manager) {
        mManager = manager; // 将FragmentManagerImpl对象传入,方便后续使用
        mReorderingAllowed = mManager.getTargetSdk() > Build.VERSION_CODES.N_MR1; // 是否允许重新组合  ? SDK > 25
    }

2. .add(current, FRAGMENT_TAG) // 进行添加操作 返回BackStackRecord对象

从上面第一步的分析可以知道 开始调用BackStackRecord.add()方法

    public FragmentTransaction add(Fragment fragment, String tag) {
    	// 添加操作 0, RequestManagerFragment  "com.bumptech.glide.manager"  1
        doAddOp(0, fragment, tag, OP_ADD);
        return this; // 并返回当前对象
    }

	//  0, RequestManagerFragment  "com.bumptech.glide.manager"  1 对应的参数信息
    private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
        if (mManager.getTargetSdk() > Build.VERSION_CODES.N_MR1) { // 判断SDK > 25
        	// 获取fragment对应的class类 RequestManagerFragment.class
            final Class fragmentClass = fragment.getClass(); 
            // 因为RequestManagerFragment使用public修饰的 所以这里返回1
            final int modifiers = fragmentClass.getModifiers(); 
            if ((fragmentClass.isAnonymousClass()  // 匿名类
            	|| !Modifier.isPublic(modifiers)  || // 非public
            	(fragmentClass.isMemberClass() && !Modifier.isStatic(modifiers)))) { // 成员类 && 不是static 抛出异常
                throw new IllegalStateException("Fragment " + fragmentClass.getCanonicalName()
                        + " must be a public static class to be  properly recreated from"
                        + " instance state.");
            }
        }
        fragment.mFragmentManager = mManager; // 将之前的fm实现类赋值给fragment的fragment管理者
        if (tag != null) { // tag不为空
        	// fragment的tag也不为空 && tag与fragment.tag不一致时 抛出异常信息
            if (fragment.mTag != null && !tag.equals(fragment.mTag)) { 
                throw new IllegalStateException("Can't change tag of fragment "
                        + fragment + ": was " + fragment.mTag
                        + " now " + tag);
            }
            // 将tag 赋值给fragment的tag
            fragment.mTag = tag;
        }

        if (containerViewId != 0) { // 我们这里是为 0 
            if (containerViewId == View.NO_ID) { // containerViewId == -1 抛出异常
                throw new IllegalArgumentException("Can't add fragment "
                        + fragment + " with tag " + tag + " to container view with no id");
            }
            // mFragmentId 有值的情况 判断当前值与传递过来是否一致 不一致则抛出异常
            if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) { 
                throw new IllegalStateException("Can't change container ID of fragment "
                        + fragment + ": was " + fragment.mFragmentId
                        + " now " + containerViewId);
            }
            fragment.mContainerId = fragment.mFragmentId = containerViewId; // 给 mFragmentId mContainerId进行赋值
        }
        addOp(new Op(opcmd, fragment)); // 创建一个Op对象 并将Op对象添加到mOps集合中
    }
    void addOp(Op op) {
        mOps.add(op); // 添加到ArrayList集合中
        op.enterAnim = mEnterAnim; // 设置进入动画
        op.exitAnim = mExitAnim; // 设置退出动画
        op.popEnterAnim = mPopEnterAnim; // pop进入动画
        op.popExitAnim = mPopExitAnim; // pop退出动画
    }
    // BackStackRecord # Op 类
        Op(int cmd, Fragment fragment) {
            this.cmd = cmd; // 执行命令 == 1
            this.fragment = fragment; // RequestManagerFragment示例
        }
fragmentClass.getModifiers(); 获取对象对应的int值

PUBLIC: 1
PRIVATE: 2
PROTECTED: 4
STATIC: 8
FINAL: 16
SYNCHRONIZED: 32
VOLATILE: 64
TRANSIENT: 128
NATIVE: 256
INTERFACE: 512
ABSTRACT: 1024
STRICT: 2048

3. .commitAllowingStateLoss(); // 提交 允许状态丢失

根据add的返回 当前方法的执行依旧是在BackStackRecord中进行执行

    public int commitAllowingStateLoss() { // 允许状态丢失
        return commitInternal(true);
    }
    int commitInternal(boolean allowStateLoss) { // true
        if (mCommitted) { // 已经被执行
            throw new IllegalStateException("commit already called");
        }
        if (FragmentManagerImpl.DEBUG) { // debug模式 进行打印log处理
            Log.v(TAG, "Commit: " + this); // log打印
            LogWriter logw = new LogWriter(Log.VERBOSE, TAG); // LogWriter初始化
            PrintWriter pw = new FastPrintWriter(logw, false, 1024); // FastPrintWriter初始化
            dump("  ", null, pw, null); // 开始执行dump打印
            pw.flush(); // 会执行 close() 关闭流
        }
        mCommitted = true; // 表示当前正在被执行
        if (mAddToBackStack) { // 添加到回退栈中
            mIndex = mManager.allocBackStackIndex(this); // 将当前的FragmentTransaction添加到mManager中
        } else {
            mIndex = -1;
        }
        mManager.enqueueAction(this, allowStateLoss); // 队列中去进行操作
        return mIndex;
    }
mManager.allocBackStackIndex(this); // 添加到回退栈 添加之后并返回当前index值
FragmentManagerImpl.allocBackStackIndex(BackStackRecord)
    public int allocBackStackIndex(BackStackRecord bse) {
        synchronized (this) { // 进行加锁处理
            if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) { // 如果集合为空 就行初始化
                if (mBackStackIndices == null) {
                    mBackStackIndices = new ArrayList<BackStackRecord>();
                }
                int index = mBackStackIndices.size();
                if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse);
                mBackStackIndices.add(bse);
                return index; // 返回当前添加的位置的index值
            } else { // 不为空的情况下添加到当前集合中的最后一个位置 如果当前集合有1个数据 即将下标为0的数据进行覆盖操作
                int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1);
                if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse);
                mBackStackIndices.set(index, bse);
                return index;
            }
        }
    }
mManager.enqueueAction(this, allowStateLoss);
    public void enqueueAction(OpGenerator action, boolean allowStateLoss) { // BackStackRecord  true
        if (!allowStateLoss) { // 不允许状态丢失
        	// 1. 当前方法需要在 界面执行 onSaveInstanceState 之后进行执行 
        	// 2. mNoTransactionsBecause 未进行事务原因不为null 将抛出异常事件
            checkStateLoss(); 
        }
        synchronized (this) { // 线程安全着想 使用关键字
        	// 因为mManager是Activity的 所以mHost不为null
            if (mDestroyed || mHost == null) { // 已经销毁 或者是 mHost == null  抛出异常 activity界面已经销毁
                if (allowStateLoss) { // 允许状态丢失 就直接返回 不会抛出异常
                    // This FragmentManager isn't attached, so drop the entire transaction.
                    return;
                }
                throw new IllegalStateException("Activity has been destroyed");
            }
            if (mPendingActions == null) { // 如果ArrayList集合为null 初始化集合
                mPendingActions = new ArrayList<>();
            }
            mPendingActions.add(action); // 向集合中添加事务 BackStackRecord
            scheduleCommit(); // 计划提交
        }
    }
    private void scheduleCommit() {
        synchronized (this) {
        	// 判断不为空 ,并且length > 0  mPostponedTransactions由于前面没有进行赋值 这个为false
            boolean postponeReady =
                    mPostponedTransactions != null && !mPostponedTransactions.isEmpty(); 
            // mPendingActions 因为在上一个方法中进行了初始化和add操作 所以 pendingReady = true
            boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
            if (postponeReady || pendingReady) { // pendingReady == true 执行方法里面的数据
            	// mHost.getHandler() 这个mHost中的Handler对应的是activity.handler  activity.handler是在主线程中进行处理的
                mHost.getHandler().removeCallbacks(mExecCommit); // 如果之前的有 就移除之前Runnable操作
                mHost.getHandler().post(mExecCommit); // 将当前任务添加到Handler中
            }
        }
    }
mExecCommit Runnable方法
    Runnable mExecCommit = new Runnable() {
        @Override
        public void run() {
            execPendingActions();
        }
    };
    /**
     * Only call from main thread! 只能在主线程中进行执行
     */
    public boolean execPendingActions() {
        ensureExecReady(true); // 确认开始之前的准备

        boolean didSomething = false;
        // 进入到当前的while循环中 while循环会执行一次 下一次mPendingActions没有数据了
        while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) { 
            mExecutingActions = true; // 执行动作为 true
            try {
                removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
            } finally {
                cleanupExec(); // 清除执行 mExecutingActions = false; mTmpIsPop.clear(); mTmpRecords.clear();
            }
            didSomething = true;
        }
        // 最终当前的状态改变
        doPendingDeferredStart();
        //为了防止列表修改错误,mActive将值设置为null,而不是当fragment变得不活动时移除它们。这会在最后清理列表事务执行结束。
        burpActive(); 
        return didSomething;
    }
    
    private void ensureExecReady(boolean allowStateLoss) {
    	// 1. 判断事务是否已经执行 执行了 则抛出异常
        if (mExecutingActions) {
            throw new IllegalStateException("FragmentManager is already executing transactions");
        }
    	// 2. 是否是从主线程开始调用 必须从片段主机的主线程调用
        if (Looper.myLooper() != mHost.getHandler().getLooper()) {
            throw new IllegalStateException("Must be called from main thread of fragment host");
        }
    	// 3. 是否允许状态丢失 1). onSaveInstanceState在方法之后调用 2). 之前已经出现异常
        if (!allowStateLoss) {
            checkStateLoss();
        }
		// mTmpRecords 集合为空 初始化当前集合和mTmpIsPop集合
        if (mTmpRecords == null) {
            mTmpRecords = new ArrayList<>();
            mTmpIsPop = new ArrayList<>();
        }
        mExecutingActions = true; // 执行动作设置为 true
        try {
            executePostponedTransaction(null, null); // 执行延迟事务 这里主要针对mPostponedTransactions集合 不管
        } finally {
            mExecutingActions = false; // 执行动作为false
        }
    }
generateOpsForPendingActions(mTmpRecords, mTmpIsPop)
    private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records,
            ArrayList<Boolean> isPop) {
        boolean didSomething = false;
        synchronized (this) { // 加锁处理
        	// mPendingActions != null size == 1
            if (mPendingActions == null || mPendingActions.size() == 0) {
                return false;
            }
            final int numActions = mPendingActions.size(); // 1
            for (int i = 0; i < numActions; i++) {
                didSomething |= mPendingActions.get(i).generateOps(records, isPop); // 返回为true
                // didSomething = false | true  = true
            }
            mPendingActions.clear(); // 从集合中清除
            mHost.getHandler().removeCallbacks(mExecCommit); // 从handler中移除掉
        }
        return didSomething; // 返回true
    }
mPendingActions.get(i).generateOps(records, isPop); BackStackRecord.generateOps(null,null)
    @Override
    public boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop) {
        if (FragmentManagerImpl.DEBUG) {
            Log.v(TAG, "Run: " + this); // log打印
        }
        records.add(this); // 添加到集合records中
        isRecordPop.add(false); // isRecordPop添加一个false
        if (mAddToBackStack) { // 是否添加到后退栈
            mManager.addBackStackState(this); 
        }
        return true; // 返回为true
    }
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
    private void removeRedundantOperationsAndExecute(ArrayList<BackStackRecord> records,
            ArrayList<Boolean> isRecordPop) {
        if (records == null || records.isEmpty()) { // records 不为空
            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); // 主要是针对mPostponedTransactions集合,目前集合为null

        final int numRecords = records.size(); // 1
        int startIndex = 0;
        for (int recordNum = 0; recordNum < numRecords; recordNum++) { // for会执行一次
            final boolean canReorder = records.get(recordNum).mReorderingAllowed; // 判断SDK > 25 ? true : false
            if (!canReorder) {
                // execute all previous transactions 执行以前所有事务
                if (startIndex != recordNum) { // startIndex = 0  recordNum = 1 
                    executeOpsTogether(records, isRecordPop, startIndex, recordNum);
                }
                // execute all pop operations that don't allow reordering together or 
                // one add operation  执行所有不允许一起重新排序的pop操作或一次添加操作
                int reorderingEnd = recordNum + 1;
                if (isRecordPop.get(recordNum)) {
                    while (reorderingEnd < numRecords
                            && isRecordPop.get(reorderingEnd)
                            && !records.get(reorderingEnd).mReorderingAllowed) {
                        reorderingEnd++;
                    }
                }
                executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
                startIndex = reorderingEnd;
                recordNum = reorderingEnd - 1;
            }
        }
        if (startIndex != numRecords) { // 不会执行 
            executeOpsTogether(records, isRecordPop, startIndex, numRecords);
        }
    }

    private void executePostponedTransaction(ArrayList<BackStackRecord> records,
            ArrayList<Boolean> isRecordPop) {
         // 之前未进行赋值 所以 mPostponedTransactions集合为 null 不会进入到for循环中
        int numPostponed = mPostponedTransactions == null ? 0 : mPostponedTransactions.size();
        for (int i = 0; i < numPostponed; i++) {
            StartEnterTransitionListener listener = mPostponedTransactions.get(i);
            if (records != null && !listener.mIsBack) {
                int index = records.indexOf(listener.mRecord);
                if (index != -1 && isRecordPop.get(index)) {
                    listener.cancelTransaction();
                    continue;
                }
            }
            if (listener.isReady() || (records != null &&
                    listener.mRecord.interactsWith(records, 0, records.size()))) {
                mPostponedTransactions.remove(i);
                i--;
                numPostponed--;
                int index;
                if (records != null && !listener.mIsBack &&
                        (index = records.indexOf(listener.mRecord)) != -1 &&
                        isRecordPop.get(index)) {
                    // This is popping a postponed transaction
                    listener.cancelTransaction();
                } else {
                    listener.completeTransaction();
                }
            }
        }
    }
executeOpsTogether(records, isRecordPop, startIndex, recordNum); 0, 1 // 执行Ops
    private void executeOpsTogether(ArrayList<BackStackRecord> records,
            ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
        final boolean allowReordering = records.get(startIndex).mReorderingAllowed; // SDK > 25
        boolean addToBackStack = false;
        if (mTmpAddedFragments == null) { // 集合为null 进行初始化
            mTmpAddedFragments = new ArrayList<>();
        } else {
            mTmpAddedFragments.clear(); // 不为空 清楚所有数据
        }
        mTmpAddedFragments.addAll(mAdded); // mAdded 集合为null
        Fragment oldPrimaryNav = getPrimaryNavigationFragment(); // 获取对应的 mPrimaryNav 前面没有进行设置 为 null
        for (int recordNum = startIndex; recordNum < endIndex; recordNum++) { // 执行一次
            final BackStackRecord record = records.get(recordNum); // 获取之前对应的BackStackRecord对象
            final boolean isPop = isRecordPop.get(recordNum); // 为false
            if (!isPop) { // 进入if执行
            	// mTmpAddedFragments集合中添加目标fragment对象  oldPrimaryNav == null
                oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav); // 根据命令返回对应的fragment
            } else {
            	// 如果cmd是add/attach 则mTmpAddedFragments进行移除目标fragment对象
            	// 如果cmd是remove/detach 则mTmpAddedFragments进行添加目标fragment对象
                record.trackAddedFragmentsInPop(mTmpAddedFragments); // 从record中移除对应的fragment对象
            }
            addToBackStack = addToBackStack || record.mAddToBackStack; // 两个数值都为false
        }
        mTmpAddedFragments.clear(); // 集合进行清除

        if (!allowReordering) { // 如果 SDK<=25 进入if语句
            FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex,
                    false); // 开始事务 会进行直接fragment中view的创建/进入动画 显示布局
        }
        executeOps(records, isRecordPop, startIndex, endIndex); // 开始设置当前fragment的下一个事务 和 状态更改

        int postponeIndex = endIndex;
        if (allowReordering) { // SDK > 25
            ArraySet<Fragment> addedFragments = new ArraySet<>();
            addAddedFragments(addedFragments); //将当前mAdded中所有的fragment添加到addedFragments
            postponeIndex = postponePostponableTransactions(records, isRecordPop,
                    startIndex, endIndex, addedFragments); // 将延迟的事务添加到集合addedFragments中 并获取延迟开始执行下标
            makeRemovedFragmentsInvisible(addedFragments); // 因为延迟导致的fragment界面 将其alpha设为0
        }

        if (postponeIndex != startIndex && allowReordering) { 
            // need to run something now
            FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
                    postponeIndex, true); // 执行界面的初始化onViewCreate等操作 并开始显示
            moveToState(mCurState, true); // 移除当前状态 CREATE
        }

        for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
            final BackStackRecord record = records.get(recordNum);
            final boolean isPop = isRecordPop.get(recordNum);
            if (isPop && record.mIndex >= 0) {
                freeBackStackIndex(record.mIndex); // 释放返回栈索引
                record.mIndex = -1;
            }
            record.runOnCommitRunnables(); // mCommitRunnables集合中Runnable开始执行 然后mCommitRunnables置空
        }

        if (addToBackStack) {
            reportBackStackChanged(); // 调用监听 执行 onBackStackChanged方法
        }
    }
record.expandOps(mTmpAddedFragments, oldPrimaryNav);
    Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
        for (int opNum = 0; opNum < mOps.size(); opNum++) { // 之前的代码添加了一个数据 Op对象  执行一次
            final Op op = mOps.get(opNum); 
            switch (op.cmd) { // cmd = OP_ADD
                case OP_ADD:
                case OP_ATTACH:
                    added.add(op.fragment); // 将op对应的fragment添加到added集合中
                    break; // 退出switch
                case OP_REMOVE:
                case OP_DETACH: {
                    added.remove(op.fragment);
                    if (op.fragment == oldPrimaryNav) {
                        mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.fragment));
                        opNum++;
                        oldPrimaryNav = null;
                    }
                }
                break;
                case OP_REPLACE: {
                    final Fragment f = op.fragment;
                    final int containerId = f.mContainerId;
                    boolean alreadyAdded = false;
                    for (int i = added.size() - 1; i >= 0; i--) {
                        final Fragment old = added.get(i);
                        if (old.mContainerId == containerId) {
                            if (old == f) {
                                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;
                                }
                                final Op removeOp = new Op(OP_REMOVE, old);
                                removeOp.enterAnim = op.enterAnim;
                                removeOp.popEnterAnim = op.popEnterAnim;
                                removeOp.exitAnim = op.exitAnim;
                                removeOp.popExitAnim = op.popExitAnim;
                                mOps.add(opNum, removeOp);
                                added.remove(old);
                                opNum++;
                            }
                        }
                    }
                    if (alreadyAdded) {
                        mOps.remove(opNum);
                        opNum--;
                    } else {
                        op.cmd = OP_ADD;
                        added.add(f);
                    }
                }
                break;
                case OP_SET_PRIMARY_NAV: {
                    // It's ok if this is null, that means we will restore to no active
                    // primary navigation fragment on a pop.
                    mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, oldPrimaryNav));
                    opNum++;
                    // Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
                    oldPrimaryNav = op.fragment;
                }
                break;
            }
        }
        return oldPrimaryNav; // 返回对应的fragment
    }
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex, false); 这个方法不进行详解,代码有点多了.大概流程如下
	// 参数对应的value整理 
	// fragmentManager : activity.getFragmentManager() 
	// records 含有一个元素 
	// isRecordPop : 含有一个元素值为false 
	// startIndex : 0
	// endIndex : 1
	// isReordered : false 如果当前的SDK版本大于25 即为true
    static void startTransitions(FragmentManagerImpl fragmentManager,
            ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop,
            int startIndex, int endIndex, boolean isReordered) {
        if (fragmentManager.mCurState < Fragment.CREATED) { // fragmentManager对应界面的状态判断
            return;
        }
        SparseArray<FragmentContainerTransition> transitioningFragments =
                new SparseArray<>(); // 初始化集合
        for (int i = startIndex; i < endIndex; i++) { // 根据前面代码 这个方法会执行一次
            final BackStackRecord record = records.get(i); // 对应的RequestManagerFragment的对象
            final boolean isPop = isRecordPop.get(i); // false
            if (isPop) { // 是否弹出
                calculatePopFragments(record, transitioningFragments, isReordered);
            } else {
            	//mContainerId != 0 对集合transitioningFragments添加数据 并开始执行 ensureInflatedFragmentView()中的方法 进行View的相关初始化
            	// mContainerId == 0 transitioningFragments集合为null
                calculateFragments(record, transitioningFragments, isReordered); 
            }
        }
        if (transitioningFragments.size() != 0) { // 集合不为0 的情况  根据上面的calculateFragments()进行添加操作
        	// 获取当前界面对应的activity Context
            final View nonExistentView = new View(fragmentManager.mHost.getContext()); 
            final int numContainers = transitioningFragments.size(); // size = 1
            for (int i = 0; i < numContainers; i++) { // 执行一次当前操作
                int containerId = transitioningFragments.keyAt(i); // 获取对应的containerId 0/
                // 根据资源Element获取对应的name和对应的getTransitionName ,将name和对应的getTransitionName添加到集合中 并返回
                ArrayMap<String, String> nameOverrides = calculateNameOverrides(containerId,
                        records, isRecordPop, startIndex, endIndex);
				// 获取当前下标的fragment内容事务
                FragmentContainerTransition containerTransition = transitioningFragments.valueAt(i);

                if (isReordered) { // SDK > 25 下面的代码均开始执行进入视图 或者退出视图 界面的显示
                    configureTransitionsReordered(fragmentManager, containerId,
                            containerTransition, nonExistentView, nameOverrides);
                } else {
                    configureTransitionsOrdered(fragmentManager, containerId,
                            containerTransition, nonExistentView, nameOverrides);
                }
            }
        }
    }
FragmentTransition. calculatePopFragments() // 弹出fragment
	// transaction : 对应需要添加的fragment对象
	// transitioningFragments 空集合
	// isReordered SDK > 25 ? true : false
    public static void calculatePopFragments(BackStackRecord transaction,
            SparseArray<FragmentContainerTransition> transitioningFragments, boolean isReordered) {
        if (!transaction.mManager.mContainer.onHasView()) { // 如果容器包含任何视图,则返回true 
            return; // nothing to see, so no transitions 没有什么可以看的 所以没有过渡
        }
        final int numOps = transaction.mOps.size(); // 获取集合中对应Op对象的size
        for (int opNum = numOps - 1; opNum >= 0; opNum--) { // 遍历所有的Op对象
            final BackStackRecord.Op op = transaction.mOps.get(opNum); // 获取对应下标的Op对象
            addToFirstInLastOut(transaction, op, transitioningFragments, true, isReordered);
        }
    }
FragmentTransition. calculateFragments() // 非弹出fragment
	// transaction : 对应需要添加的fragment对象
	// transitioningFragments 空集合
	// isReordered SDK > 25 ? true : false
    public static void calculateFragments(BackStackRecord transaction,
            SparseArray<FragmentContainerTransition> transitioningFragments,
            boolean isReordered) {
        final int numOps = transaction.mOps.size(); // 获取transaction中Op对象的大小
        for (int opNum = 0; opNum < numOps; opNum++) { // 进行遍历
            final BackStackRecord.Op op = transaction.mOps.get(opNum); // 获取对应下标的Op对象
            addToFirstInLastOut(transaction, op, transitioningFragments, false, isReordered);
        }
    }
FragmentTransition . addToFirstInLastOut()
    private static void addToFirstInLastOut(BackStackRecord transaction, BackStackRecord.Op op,
            SparseArray<FragmentContainerTransition> transitioningFragments, boolean isPop, // 唯一不同的变量  
            boolean isReorderedTransaction) {
        final Fragment fragment = op.fragment; // 获取当前op中的fragment实例对象
        if (fragment == null) { // 为空 则直接返回
            return; // no fragment, no transition
        }
        final int containerId = fragment.mContainerId; // 获取fragment的mContainerId
        if (containerId == 0) { // 为0 则直接返回
            return; // no container, no transition
        }
        // op.cmd == OP_ADD  ispop ? OP_REMOVE : OP_ADD
        final int command = isPop ? INVERSE_OPS[op.cmd] : op.cmd; // 获取是否是弹出
        boolean setLastIn = false; // 最后
        boolean wasRemoved = false; // 移除
        boolean setFirstOut = false; // 先出
        boolean wasAdded = false; // 添加
        switch (command) {
            case BackStackRecord.OP_SHOW:
                if (isReorderedTransaction) { // SDK > 25
                    setLastIn = fragment.mHiddenChanged && !fragment.mHidden &&
                            fragment.mAdded; // 显示与隐藏状态更改 & 不显示 & 已添加
                } else {
                    setLastIn = fragment.mHidden; // 隐藏
                }
                wasAdded = true; // 已经添加
                break;
            case BackStackRecord.OP_ADD:
            case BackStackRecord.OP_ATTACH:
                if (isReorderedTransaction) { // SDK > 25
                    setLastIn = fragment.mIsNewlyAdded; // 是否是新增加的
                } else {
                    setLastIn = !fragment.mAdded && !fragment.mHidden; // 未添加 & 不显示
                }
                wasAdded = true; // 已添加
                break;
            case BackStackRecord.OP_HIDE:
                if (isReorderedTransaction) { // SDK > 25
                    setFirstOut = fragment.mHiddenChanged && fragment.mAdded &&
                            fragment.mHidden; // 显示与隐藏状态更改 & 已添加 & 显示
                } else {
                    setFirstOut = fragment.mAdded && !fragment.mHidden; // 已添加 & 显示
                }
                wasRemoved = true; // 移除
                break;
            case BackStackRecord.OP_REMOVE:
            case BackStackRecord.OP_DETACH:
                if (isReorderedTransaction) { // SDK > 25
                    setFirstOut = !fragment.mAdded && fragment.mView != null // 未添加 & view != null & 显示 & alpha > 0
                            && fragment.mView.getVisibility() == View.VISIBLE
                            && fragment.mView.getTransitionAlpha() > 0; // 
                } else {
                    setFirstOut = fragment.mAdded && !fragment.mHidden; // 已添加 & 显示
                }
                wasRemoved = true; // 移除
                break;
        } 
        // setLastIn = true wasAdded = true setFirstOut = false wasRemoved = false
        // 根据containerId获取对应的FragmentContainerTransition fragment内容事务
        FragmentContainerTransition containerTransition = transitioningFragments.get(containerId);
        if (setLastIn) { // 未显示在界面即为true
        	// containerTransition如果为null进行初始化,并将初始化之后的对象和containerId放入到集合中transitioningFragments
            containerTransition =
                    ensureContainer(containerTransition, transitioningFragments, containerId); 
            containerTransition.lastIn = fragment;// 对应添加的op.fragment
            containerTransition.lastInIsPop = isPop; // 是否弹出
            containerTransition.lastInTransaction = transaction;//BackStackRecord
        }
        if (!isReorderedTransaction && wasAdded) { // SDK > 25 & 执行show/add/attach
            if (containerTransition != null && containerTransition.firstOut == fragment) {
                containerTransition.firstOut = null;
            }

            /*
             * Ensure that fragments that are entering are at least at the CREATED state
             * so that they may load Transitions using TransitionInflater.
             */
            FragmentManagerImpl manager = transaction.mManager; // fragment中对应的fragmentManager
            if (fragment.mState < Fragment.CREATED && manager.mCurState >= Fragment.CREATED &&
                    manager.mHost.getContext().getApplicationInfo().targetSdkVersion >=
                            Build.VERSION_CODES.N && !transaction.mReorderingAllowed) { // 状态判断和 SDK版本的判断
                manager.makeActive(fragment); // 如果mIndex == -1 进行设置 mIndex = 0
                // 启动状态处理 当前fragment的新状态为Fragment.CREATED 
                manager.moveToState(fragment, Fragment.CREATED, 0, 0, false);
                // 开始执行performCreateView
                // 如果fragment中的view不为空的话 就开始执行fragment.onViewCreate方法 
                // 并且开始分发view的创建 dispatchOnFragmentViewCreated
            }
        }
        if (setFirstOut && (containerTransition == null || containerTransition.firstOut == null)) {
        	// containerTransition如果为null进行初始化,并将初始化之后的对象和containerId放入到集合中transitioningFragments
            containerTransition =
                    ensureContainer(containerTransition, transitioningFragments, containerId);
            containerTransition.firstOut = fragment; // 对应添加的op.fragment
            containerTransition.firstOutIsPop = isPop; // 是否弹出
            containerTransition.firstOutTransaction = transaction; //BackStackRecord
        }
		// SDK > 25 & 已经隐藏
        if (!isReorderedTransaction && wasRemoved &&
                (containerTransition != null && containerTransition.lastIn == fragment)) {
            containerTransition.lastIn = null; // 置空处理
        }
    }
    // containerTransition 内容事务为null进行初始化,并将containerTransition和对应的containerId放到集合中 并返回创建之后的对象
    private static FragmentContainerTransition ensureContainer(
            FragmentContainerTransition containerTransition,
            SparseArray<FragmentContainerTransition> transitioningFragments, int containerId) {
        if (containerTransition == null) {
            containerTransition = new FragmentContainerTransition();
            transitioningFragments.put(containerId, containerTransition);
        }
        return containerTransition;
    }
FragmentTransition . calculateNameOverrides()
	// containerId : 0 records : 集合 isRecordPop : 集合false startIndex : 0 endIndex : 1
    private static ArrayMap<String, String> calculateNameOverrides(int containerId,
            ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop,
            int , int endIndex) {
        ArrayMap<String, String> nameOverrides = new ArrayMap<>();
        for (int recordNum = endIndex - 1; recordNum >= startIndex; recordNum--) { // 循环执行一次
            final BackStackRecord record = records.get(recordNum); // 获取对应的BackStackRecord对象
            if (!record.interactsWith(containerId)) { // 如果当前fragment != null 并且mContainerId != 0 即返回 true 继续向下执行
                continue;
            }
            final boolean isPop = isRecordPop.get(recordNum); // 获取 false
            if (record.mSharedElementSourceNames != null) { // 获取之前对应的Element资源信息
                final int numSharedElements = record.mSharedElementSourceNames.size(); //资源信息的名称
                final ArrayList<String> sources;
                final ArrayList<String> targets;
                if (isPop) { // 是否弹出操作
                    targets = record.mSharedElementSourceNames; // 资源名称
                    sources = record.mSharedElementTargetNames; // 资源名称对应的View.getTransitionName()
                } else {
                    sources = record.mSharedElementSourceNames;  // 资源名称
                    targets = record.mSharedElementTargetNames;  // 资源名称对应的View.getTransitionName()
                }
                for (int i = 0; i < numSharedElements; i++) { // 遍历所有Element
                    String sourceName = sources.get(i);
                    String targetName = targets.get(i);
                    String previousTarget = nameOverrides.remove(targetName);
                    if (previousTarget != null) { // 将数据添加到nameOverrides集合中
                        nameOverrides.put(sourceName, previousTarget);
                    } else {
                        nameOverrides.put(sourceName, targetName); 
                    }
                }
            }
        }
        return nameOverrides; // 返回当前集合
    }
FragmentTransition . configureTransitionsReordered()

configureTransitionsReordered(fragmentManager, containerId,containerTransition, nonExistentView, nameOverrides);

    private static void configureTransitionsReordered(FragmentManagerImpl fragmentManager,
            int containerId, FragmentContainerTransition fragments,
            View nonExistentView, ArrayMap<String, String> nameOverrides) {
        ViewGroup sceneRoot = null;
        if (fragmentManager.mContainer.onHasView()) { // 如果容器包含任何视图,则返回true 
            sceneRoot = fragmentManager.mContainer.onFindViewById(containerId); // 根据containerId 找到对应的ViewGroup
        }
        if (sceneRoot == null) { // 如果获取到的ViewGroup == null 直接返回
            return;
        }
        final Fragment inFragment = fragments.lastIn; // 最后
        final Fragment outFragment = fragments.firstOut; // 先出
        final boolean inIsPop = fragments.lastInIsPop; // 最后是否弹出
        final boolean outIsPop = fragments.firstOutIsPop; // 现出是否弹出

        ArrayList<View> sharedElementsIn = new ArrayList<>();
        ArrayList<View> sharedElementsOut = new ArrayList<>();
         // transition 的 close处理 inIsPop ? getReenterTransition ? getEnterTransition
        Transition enterTransition = getEnterTransition(inFragment, inIsPop);
         // transition 的 close处理 outIsPop ? getReturnTransition ? getExitTransition
        Transition exitTransition = getExitTransition(outFragment, outIsPop);
		// 主要对SharedElement进行操作 如果infragment不为null就进行显示操作
        TransitionSet sharedElementTransition = configureSharedElementsReordered(sceneRoot,
                nonExistentView, nameOverrides, fragments, sharedElementsOut, sharedElementsIn,
                enterTransition, exitTransition);

        if (enterTransition == null && sharedElementTransition == null &&
                exitTransition == null) {
            return; // no transitions! 没有事务可执行
        }
		//退出事务 配置进入退出视图
        ArrayList<View> exitingViews = configureEnteringExitingViews(exitTransition,
                outFragment, sharedElementsOut, nonExistentView);
		// 进入事务 配置进入退出视图
        ArrayList<View> enteringViews = configureEnteringExitingViews(enterTransition,
                inFragment, sharedElementsIn, nonExistentView);
		// 设置进入视图显示
        setViewVisibility(enteringViews, View.INVISIBLE);
		// 合并并过渡
        Transition transition = mergeTransitions(enterTransition, exitTransition,
                sharedElementTransition, inFragment, inIsPop);
        if (transition != null) {
            replaceHide(exitTransition, outFragment, exitingViews); // 替换隐藏
            transition.setNameOverrides(nameOverrides); // 对transition设置NameOverrides
            scheduleRemoveTargets(transition, // 计划移除目标
                    enterTransition, enteringViews, exitTransition, exitingViews,
                    sharedElementTransition, sharedElementsIn);
            TransitionManager.beginDelayedTransition(sceneRoot, transition); // 事务管理 开始延迟事务
            setViewVisibility(enteringViews, View.VISIBLE); // 设置进入视图的显示
            // Swap the shared element targets 交换共享元素目标
            if (sharedElementTransition != null) {
                sharedElementTransition.getTargets().clear();
                sharedElementTransition.getTargets().addAll(sharedElementsIn);
                replaceTargets(sharedElementTransition, sharedElementsOut, sharedElementsIn);
            }
        }
    }
FragmentTransition . configureTransitionsOrdered()

configureTransitionsOrdered(fragmentManager, containerId, containerTransition, nonExistentView, nameOverrides);

    private static void configureTransitionsOrdered(FragmentManagerImpl fragmentManager,
            int containerId, FragmentContainerTransition fragments,
            View nonExistentView, ArrayMap<String, String> nameOverrides) {
        ViewGroup sceneRoot = null;
        if (fragmentManager.mContainer.onHasView()) { // 如果容器包含任何视图,则返回true 
            sceneRoot = fragmentManager.mContainer.onFindViewById(containerId); // 获取对应的viewGroup
        }
        if (sceneRoot == null) { // viewGroup为null
            return;
        }
        final Fragment inFragment = fragments.lastIn; // 最后
        final Fragment outFragment = fragments.firstOut; // 先出
        final boolean inIsPop = fragments.lastInIsPop; // 最后是否弹出
        final boolean outIsPop = fragments.firstOutIsPop; // 先出是否弹出
		// 根据是否弹出获取对应的事务
        Transition enterTransition = getEnterTransition(inFragment, inIsPop);
        Transition exitTransition = getExitTransition(outFragment, outIsPop);

        ArrayList<View> sharedElementsOut = new ArrayList<>();
        ArrayList<View> sharedElementsIn = new ArrayList<>();
		// 配置SharedElements事务集合
        TransitionSet sharedElementTransition = configureSharedElementsOrdered(sceneRoot,
                nonExistentView, nameOverrides, fragments, sharedElementsOut, sharedElementsIn,
                enterTransition, exitTransition);

        if (enterTransition == null && sharedElementTransition == null &&
                exitTransition == null) { 
            return; // no transitions! 没有事务
        }
		// 退出事务 配置进入退出视图
        ArrayList<View> exitingViews = configureEnteringExitingViews(exitTransition,
                outFragment, sharedElementsOut, nonExistentView);
		// 退出视图为null 则直接设置退出事务为null
        if (exitingViews == null || exitingViews.isEmpty()) {
            exitTransition = null;
        }
		// 进人事务不为null
        if (enterTransition != null) {
            // Ensure the entering transition doesn't target anything until the views are made
            // visible
            enterTransition.addTarget(nonExistentView); // 添加目标View
        }
		// 合并事务
        Transition transition = mergeTransitions(enterTransition, exitTransition,
                sharedElementTransition, inFragment, fragments.lastInIsPop);

        if (transition != null) { // 事务不为null 
            transition.setNameOverrides(nameOverrides); // 设置对应的NameOverride
            final ArrayList<View> enteringViews = new ArrayList<>();
            scheduleRemoveTargets(transition, // 计划移除目标
                    enterTransition, enteringViews, exitTransition, exitingViews,
                    sharedElementTransition, sharedElementsIn);
            scheduleTargetChange(sceneRoot, inFragment, nonExistentView, sharedElementsIn, // 计划目标更改
                    enterTransition, enteringViews, exitTransition, exitingViews);

            TransitionManager.beginDelayedTransition(sceneRoot, transition); // 事务管理 开始延迟事务
        }
    }
executeOps(records, isRecordPop, startIndex, endIndex);
    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); // false
            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.fragment.mBackStackNesting += 1;
                record.executeOps(); 
                // f.setNextTransition(mTransition, mTransitionStyle); // 设置下一个事务
                // f.setNextAnim(op.enterAnim); // 设置下一个动画 进入动画
                // mManager.moveToState(mManager.mCurState, true); // 移除状态
            }
        }
    }

以上只是仅供学习参考.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值