美文网首页
Android-Fragment的生命周期处理源码分析

Android-Fragment的生命周期处理源码分析

作者: zzq_nene | 来源:发表于2020-12-11 15:02 被阅读0次

    从FragmentActivity开始分析:

    在FragmentActivity中有一个FragmentController对象mFragments,该对象的创建和初始化如下:

    final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
    

    1.HostCallbacks的初始化

    new HostCallbacks()的操作其实很简单,HostCallbacks是FragmentActivity的内部类,是继承自FragmentHostCallback的,而new HostCallbacks最终是调用到了FragmentHostCallback的构造器。FragmentHostCallback的构造器其实就是保存了相应的上下文对象,创建了Handler,该Handler是用来进行异步提交处理Runnable任务的。

    FragmentHostCallback(@Nullable Activity activity, @NonNull Context context,
            @NonNull Handler handler, int windowAnimations) {
        mActivity = activity;
        mContext = Preconditions.checkNotNull(context, "context == null");
        mHandler = Preconditions.checkNotNull(handler, "handler == null");
        // mWindowAnimations其实是等于0
        mWindowAnimations = windowAnimations;
    }
    

    在创建HostCallbacks对象的时候,其父类FragmentHostCallback又会创建一个FragmentManager对象mFragmentManager,其实现类是FragmentManagerImpl。

    2.FragmentController#createController

    FragmentController的对象创建其实很简单,其构造器是私有的,所有通过静态方法创建。

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

    3.FragmentActivity#onCreate

    FragmentActivity作为Activity的生命周期开始位置,则也会通过mFragments这个FragmentController对象进行生命周期的分发,然后执行Fragment的生命周期

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        mFragments.attachHost(null /*parent*/);
        // 这里是状态恢复的情况下才会执行
        if (savedInstanceState != null) {
            // 从内存中取出状态保存是保存的数据
            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
            mFragments.restoreSaveState(p);
    
            // Check if there are any pending onActivityResult calls to descendent Fragments.
            if (savedInstanceState.containsKey(NEXT_CANDIDATE_REQUEST_INDEX_TAG)) {
                mNextCandidateRequestIndex =
                        savedInstanceState.getInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG);
                int[] requestCodes = savedInstanceState.getIntArray(ALLOCATED_REQUEST_INDICIES_TAG);
                String[] fragmentWhos = savedInstanceState.getStringArray(REQUEST_FRAGMENT_WHO_TAG);
                if (requestCodes == null || fragmentWhos == null ||
                            requestCodes.length != fragmentWhos.length) {
                    Log.w(TAG, "Invalid requestCode mapping in savedInstanceState.");
                } else {
                    mPendingFragmentActivityResults = new SparseArrayCompat<>(requestCodes.length);
                    for (int i = 0; i < requestCodes.length; i++) {
                        mPendingFragmentActivityResults.put(requestCodes[i], fragmentWhos[i]);
                    }
                }
            }
        }
    
        if (mPendingFragmentActivityResults == null) {
            mPendingFragmentActivityResults = new SparseArrayCompat<>();
            mNextCandidateRequestIndex = 0;
        }
    
        super.onCreate(savedInstanceState);
    
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        // 向FragmentController分发生命周期事件
        mFragments.dispatchCreate();
    }
    

    4.FragmentController#attachHost

    public void attachHost(@Nullable Fragment parent) {
        // 这里的mHost是FragmentHostCallback的子类对象,mFragmentManager
        // 是FragmentManager对象,其实现类是FragmentManagerImpl
        // 这里会初始化FragmentManager中的mContainer容器对象,该勇气是在Fragment创建
        // ContentView的时候使用的,因为该
        mHost.mFragmentManager.attachController(
                mHost, mHost /*container*/, parent);
    }
    

    5.FragmentManager#attachController

    这里其实就是做一定的数据绑定,把对应的Fragment、还有HostCallbacks等于FragmentManager做绑定,不过这里的mParent是为null的。因为在FragmentActivity传入的时候就是传的null

    void attachController(@NonNull FragmentHostCallback<?> host,
            @NonNull FragmentContainer container, @Nullable final Fragment parent) {
        if (mHost != null) throw new IllegalStateException("Already attached");
        mHost = host;
        mContainer = container;
        mParent = parent;
        if (mParent != null) {
            // 这里取决于是否依赖有导航的Fragment
            updateOnBackPressedCallbackEnabled();
        }
        // 设置点击backPressed的回调
        if (host instanceof OnBackPressedDispatcherOwner) {
            OnBackPressedDispatcherOwner dispatcherOwner = ((OnBackPressedDispatcherOwner) host);
            mOnBackPressedDispatcher = dispatcherOwner.getOnBackPressedDispatcher();
            LifecycleOwner owner = parent != null ? parent : dispatcherOwner;
            mOnBackPressedDispatcher.addCallback(owner, mOnBackPressedCallback);
        }
    
        // 获取对应的FragmentManager的视图模型
        if (parent != null) {
            mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
        } else if (host instanceof ViewModelStoreOwner) {
            ViewModelStore viewModelStore = ((ViewModelStoreOwner) host).getViewModelStore();
            mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);
        } else {
            mNonConfig = new FragmentManagerViewModel(false);
        }
    }
    

    6.FragmentController#dispatchCreate

    FragmentController中的很多操作,其实都是通过HostCallbacks中的mFragmentManager对象,调用到FragmentManager或者FragmentManagerImpl中对应的方法。

    public void dispatchCreate() {
        // 调用FragmentManager#dispatchCreate方法
        mHost.mFragmentManager.dispatchCreate();
    }
    

    7.FragmentManager#dispatchCreate

    其实FragmentManager中有许多分发生命周期的方法,比如dispatchActivityCreated,就是在FragmentActivity中的onStart中调用,在dispatchStart之前,这些dispatch方法分发生命周期,其实最终都是调用到了一个方法:dispatchStateChange。只不过传入的参数不同,用来代表不同的生命周期时期。

    void dispatchCreate() {
        // mStateSaved是表示状态保存的标志。只有在保存状态的时候才会设置为true
        mStateSaved = false;
        mStopped = false;
        // 在onCreate中调用的,就是传入Fragment.CREATED
        // 如果实在onStart中调用的,则会传入的是Fragment.ACTIVITY_CREATED和
        // Fragment.STARTED
        dispatchStateChange(Fragment.CREATED);
    }
    

    在Fragment中,最新的AndroidX的版本,只有六个状态:

    static final int INITIALIZING = -1;    // Not yet attached.
    static final int ATTACHED = 0;         // Attached to the host.
    static final int CREATED = 1;          // Created.
    static final int ACTIVITY_CREATED = 2; // Fully created, not started.
    static final int STARTED = 3;          // Created and started, not resumed.
    static final int RESUMED = 4;          // Created started and resumed.
    

    8.FragmentManager#dispatchStateChange

    这里其实主要就是调用了moveToState方法,在FragmentActivity调用FragmentController的对应的dispatch分发生命周期给Fragment的时候,最终都是调用了dispatchStateChange,而dispatchStateChange最终又是调用到了moveToState

    private void dispatchStateChange(int nextState) {
        try {
            mExecutingActions = true;
            // 向状态管理器中设置Fragment的下一个状态
            // FragmentStore中会存储当前FragmentActivity中的Fragment
            // 这里的moveToState移动Fragment的状态,会针对当前FragmentActivity中
            // 的所有的Fragment来进行
            mFragmentStore.dispatchStateChange(nextState);
            moveToState(nextState, false);
        } finally {
            mExecutingActions = false;
        }
        // 这是执行事务提交的操作的。
        // 在分发生命周期的时候,有可能有需要提交的事务
        execPendingActions(true);
    }
    

    9.FragmentStore#dispatchStateChange

    void dispatchStateChange(int state) {
        // 取出该Fragment的状态管理器,保存该Fragment的当前状态
        for (Fragment f : mAdded) {
            // 这里的mWho其实是Fragment对应的唯一标识
            FragmentStateManager fragmentStateManager = mActive.get(f.mWho);
            if (fragmentStateManager != null) {
                fragmentStateManager.setFragmentManagerState(state);
            }
        }
    
        // 遍历当前所有活跃的Fragment,设置状态
        for (FragmentStateManager fragmentStateManager : mActive.values()) {
            if (fragmentStateManager != null) {
                fragmentStateManager.setFragmentManagerState(state);
            }
        }
    }
    

    10.FragmentManager#moveToState

    将Fragment的状态修改为newState,如果FragmentManager修改状态或者always为true的话,则其他任何的Fragment也会改变状态

    void moveToState(int newState, boolean always) {
        if (mHost == null && newState != Fragment.INITIALIZING) {
            throw new IllegalStateException("No activity");
        }
        // 如果always=false,并且当前状态与新的状态一致,则不进行任何修改
        if (!always && newState == mCurState) {
            return;
        }
    
        mCurState = newState;
    
        // 从Fragment存储中取出所有已经添加的Fragment,进行遍历
        for (Fragment f : mFragmentStore.getFragments()) {
            moveFragmentToExpectedState(f);
        }
    
        // 取出所有活跃的Fragment,包括已经删除和分离的Fragment
        for (Fragment f : mFragmentStore.getActiveFragments()) {
            if (f != null && !f.mIsNewlyAdded) {
                moveFragmentToExpectedState(f);
            }
        }
        // 对延迟启动的Fragment进行状态修改
        // 这里是遍历FragmentStore中的mActive,取出活跃Fragment
        // 判断Fragment的mDeferStart是否为true
        startPendingDeferredFragments();
    
        if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
            mHost.onSupportInvalidateOptionsMenu();
            mNeedMenuInvalidate = false;
        }
    }
    

    11.FragmentManager#moveFragmentToExpectedState

    将Fragment移动到最新的状态或者是FragmentStore中FragmentStateManager中的状态,具体要取决于FragmentStore中的状态是否正确触发。
    本方法是由moveToState(int newState, boolean always)遍历触发,可能会调用多次,如果存在多个fragment的话。

    void moveFragmentToExpectedState(@NonNull Fragment f) {
        if (!mFragmentStore.containsActiveFragment(f.mWho)) {
            if (isLoggingEnabled(Log.DEBUG)) {
                Log.d(TAG, "Ignoring moving " + f + " to state " + mCurState
                        + "since it is not added to " + this);
            }
            return;
        }
        // 将Fragment状态移动到当前最新的状态
        // 这里最终调用到
        moveToState(f);
    
        if (f.mView != null) {
            // Move the view if it is out of order
            Fragment underFragment = mFragmentStore.findFragmentUnder(f);
            if (underFragment != null) {
                final View underView = underFragment.mView;
                // make sure this fragment is in the right order.
                final ViewGroup container = f.mContainer;
                int underIndex = container.indexOfChild(underView);
                int viewIndex = container.indexOfChild(f.mView);
                if (viewIndex < underIndex) {
                    container.removeViewAt(viewIndex);
                    container.addView(f.mView, underIndex);
                }
            }
            if (f.mIsNewlyAdded && f.mContainer != null) {
                // Make it visible and run the animations
                if (f.mPostponedAlpha > 0f) {
                    f.mView.setAlpha(f.mPostponedAlpha);
                }
                f.mPostponedAlpha = 0f;
                f.mIsNewlyAdded = false;
                // run animations:
                FragmentAnim.AnimationOrAnimator anim = FragmentAnim.loadAnimation(
                        mHost.getContext(), mContainer, f, true);
                if (anim != null) {
                    if (anim.animation != null) {
                        f.mView.startAnimation(anim.animation);
                    } else {
                        anim.animator.setTarget(f.mView);
                        anim.animator.start();
                    }
                }
            }
        }
        // 完成对Fragment的show或者hide操作
        if (f.mHiddenChanged) {
            completeShowHideFragment(f);
        }
    }
    

    12.FragmentManager#moveToState(Fragment f, int newState)

    本方法与上面的moveToState并不相同,是上面方法的重载。不要混淆。
    在这里改变Fragment状态的同时,会执行Fragment对应的生命周期方法,比如onCreate、onStart、onResume、onPause等方法。

    void moveToState(@NonNull Fragment f, int newState) {
        // 设置该Fragment的状态管理器
        FragmentStateManager fragmentStateManager = mFragmentStore.getFragmentStateManager(f.mWho);
        if (fragmentStateManager == null) {
            // Ideally, we only call moveToState() on active Fragments. However,
            // in restoreSaveState() we can call moveToState() on retained Fragments
            // just to clean them up without them ever being added to mActive.
            // For these cases, a brand new FragmentStateManager is enough.
            fragmentStateManager = new FragmentStateManager(mLifecycleCallbacksDispatcher, f);
            // Only allow this FragmentStateManager to go up to CREATED at the most
            fragmentStateManager.setFragmentManagerState(Fragment.CREATED);
        }
        // 对比传入的newState和Fragment状态管理器中的状态哪个更小,取出更小的状态
        newState = Math.min(newState, fragmentStateManager.computeMaxState());
        // 如果当前Fragment的状态小于新的状态
        // Fragment中的状态有6个,当当前Fragment的状态小于新的状态的时候
        // 则需要向下依次增大当前Fragment的状态,将当前Fragment的状态设置为
        // 当前状态的下一个状态
        if (f.mState <= newState) {
            // If we are moving to the same state, we do not need to give up on the animation.
            if (f.mState < newState && !mExitAnimationCancellationSignals.isEmpty()) {
                // The fragment is currently being animated...  but!  Now we
                // want to move our state back up.  Give up on waiting for the
                // animation and proceed from where we are.
                cancelExitAnimation(f);
            }
            switch (f.mState) {
                case Fragment.INITIALIZING:
                    if (newState > Fragment.INITIALIZING) {
                        if (isLoggingEnabled(Log.DEBUG)) Log.d(TAG, "moveto ATTACHED: " + f);
    
                        // 如果当前Fragment有目标Fragment,则至少需要将目标Fragment
                        // 的生命周期设置为CREATED状态
                        if (f.mTarget != null) {
                            if (!f.mTarget.equals(findActiveFragment(f.mTarget.mWho))) {
                                throw new IllegalStateException("Fragment " + f
                                        + " declared target fragment " + f.mTarget
                                        + " that does not belong to this FragmentManager!");
                            }
                            if (f.mTarget.mState < Fragment.CREATED) {
                                moveToState(f.mTarget, Fragment.CREATED);
                            }
                            f.mTargetWho = f.mTarget.mWho;
                            f.mTarget = null;
                        }
                        if (f.mTargetWho != null) {
                            Fragment target = findActiveFragment(f.mTargetWho);
                            if (target == null) {
                                throw new IllegalStateException("Fragment " + f
                                        + " declared target fragment " + f.mTargetWho
                                        + " that does not belong to this FragmentManager!");
                            }
                            if (target.mState < Fragment.CREATED) {
                                moveToState(target, Fragment.CREATED);
                            }
                        }
                        // 如果当前状态是初始化状态,而新的状态比初始化状态大
                        // 则需要将当前状态设置为下一个状态,即ATTACHED状态
                        fragmentStateManager.attach(mHost, this, mParent);
                    }
                    // fall through
                case Fragment.ATTACHED:
                    // 如果当前状态是ATTACHED状态,新的状态比当前状态大
                    // 则需要将当前Fragment的状态设置为下一个状态CREATED
                    if (newState > Fragment.ATTACHED) {
                        fragmentStateManager.create();
                    }
                    // fall through
                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) {
                        fragmentStateManager.ensureInflatedView();
                    }
    
                    if (newState > Fragment.CREATED) {
                        // 创建Fragment对应的View
                        // mContainer其实就是HostCallbacks,在FragmentActivity
                        // 的onCreate方法中调用FragmentController.attachHost
                        // 方法的时候,会将HostCallbacks对象传给FragmentController
                        fragmentStateManager.createView(mContainer);
                        fragmentStateManager.activityCreated();
                        fragmentStateManager.restoreViewState();
                    }
                    // fall through
                case Fragment.ACTIVITY_CREATED:
                    if (newState > Fragment.ACTIVITY_CREATED) {
                        fragmentStateManager.start();
                    }
                    // fall through
                case Fragment.STARTED:
                    if (newState > Fragment.STARTED) {
                        fragmentStateManager.resume();
                    }
            }
        } else if (f.mState > newState) {
            // 如果当前Fragment的状态大于新的状态
            // 说明当前Fragment已经要开始执行onPause、onStop等生命周期
            // 所以当前Fragment的状态就需要逆序依次减小
            // 比如在onPause的时候,状态就从RESUMED变成STARTED
            // 在onStop的时候,状态就从STARTED变成ACTIVITY_CREATED
            switch (f.mState) {
                case Fragment.RESUMED:
                    if (newState < Fragment.RESUMED) {
                        fragmentStateManager.pause();
                    }
                    // fall through
                case Fragment.STARTED:
                    if (newState < Fragment.STARTED) {
                        fragmentStateManager.stop();
                    }
                    // fall through
                case Fragment.ACTIVITY_CREATED:
                    // Fragment要回调onDestroyViews的时候
                    // 其实是处于ACTIVITY_CREATED这个状态
                    if (newState < Fragment.ACTIVITY_CREATED) {
                        if (isLoggingEnabled(Log.DEBUG)) {
                            Log.d(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) {
                                fragmentStateManager.saveViewState();
                            }
                        }
                        FragmentAnim.AnimationOrAnimator anim = null;
                        if (f.mView != null && f.mContainer != null) {
                            // Stop any current animations:
                            f.mContainer.endViewTransition(f.mView);
                            f.mView.clearAnimation();
                            // If parent is being removed, no need to handle child animations.
                            if (!f.isRemovingParent()) {
                                if (mCurState > Fragment.INITIALIZING && !mDestroyed
                                        && f.mView.getVisibility() == View.VISIBLE
                                        && f.mPostponedAlpha >= 0) {
                                    anim = FragmentAnim.loadAnimation(mHost.getContext(),
                                            mContainer, f, false);
                                }
                                f.mPostponedAlpha = 0;
                                // Robolectric tests do not post the animation like a real device
                                // so we should keep up with the container and view in case the
                                // fragment view is destroyed before we can remove it.
                                ViewGroup container = f.mContainer;
                                View view = f.mView;
                                if (anim != null) {
                                    f.setStateAfterAnimating(newState);
                                    FragmentAnim.animateRemoveFragment(f, anim,
                                            mFragmentTransitionCallback);
                                }
                                container.removeView(view);
                                // If the local container is different from the fragment
                                // container, that means onAnimationEnd was called, onDestroyView
                                // was dispatched and the fragment was already moved to state, so
                                // we should early return here instead of attempting to move to
                                // state again.
                                if (container != f.mContainer) {
                                    return;
                                }
                            }
                        }
                        // If a fragment has an exit animation (or transition), do not destroy
                        // its view immediately and set the state after animating
                        if (mExitAnimationCancellationSignals.get(f) == null) {
                            destroyFragmentView(f);
                        } else {
                            f.setStateAfterAnimating(newState);
                        }
                    }
                    // fall through
                case Fragment.CREATED:
                    if (newState < Fragment.CREATED) {
                        boolean beingRemoved = f.mRemoving && !f.isInBackStack();
                        if (beingRemoved || mNonConfig.shouldDestroy(f)) {
                            makeInactive(fragmentStateManager);
                        } else {
                            if (f.mTargetWho != null) {
                                Fragment target = findActiveFragment(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 (mExitAnimationCancellationSignals.get(f) != 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.
                            // Shared elements require that we wait on multiple Fragments, so if
                            // any of them are animating we will continue to wait.
                            f.setStateAfterAnimating(newState);
                            newState = Fragment.CREATED;
                        } else {
                            fragmentStateManager.destroy(mHost, mNonConfig);
                        }
                    }
                    // fall through
                case Fragment.ATTACHED:
                    if (newState < Fragment.ATTACHED) {
                        fragmentStateManager.detach(mNonConfig);
                    }
            }
        }
    
        if (f.mState != newState) {
            if (isLoggingEnabled(Log.DEBUG)) {
                Log.d(TAG, "moveToState: Fragment state for " + f + " not updated inline; "
                        + "expected state " + newState + " found " + f.mState);
            }
            f.mState = newState;
        }
    }
    

    13.FragmentManager#execPendingActions

    在针对Fragment的状态修改执行完成之后,继续分析第八步中调用的execPendingActions方法。
    execPendingActions方法只能是在主线程中执行,如果是在异步线程中,则会抛出异常。"Must be called from main thread of fragment host"
    本方法其实就是执行对应的事务,scheduleCommit方法中会执行Runnable对象mExecCommit,在mExecCommit的run方法中调用了execPendingActions方法,进行具体事务的提交。scheduleCommit是在enqueueAction调用,而enqueueAction是在事务对象BackStackRecord中的commit方法由commitInternal调用的。

    boolean execPendingActions(boolean allowStateLoss) {
        // 确保执行是处于就绪阶段,即没有正在执行的事务,也HostCallbacks也不为null
        // 且是在主线程中
        ensureExecReady(allowStateLoss);
    
        boolean didSomething = false;
        // 这里的操作,其实就是在mPendingActions中取出BackStackRecord
        // mPendingActions中存的是OpGenerator,而BackStackRecord实现了该接口
        // mTmpRecords存的就是BackStackRecord
        // 所以这里的目的就算将待执行的事务添加到mTmpRecords
        // 而在mTmpIsPop对应位置会根据是否允许添加到回退栈而设置true还是false
        // 这里如果mPendingActions为null,则直接返回false
        while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
            mExecutingActions = true;
            try {
                // 这里是删除冗余操作,并且执行事务
                // 所谓的冗余操作:比如一次事务提交,对一个Fragment进行了add
                // 又进行了remove,然后又进行了add,这样只有最后一次add有效
                // 在这里会修改事务的状态,比如将replace的事务变成ADD的
                // 最终就会执行处理事务
                // 如果没有回退栈相关,则是调用事务BackStackRecord.executeOps方法
                removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
            } finally {
                cleanupExec();
            }
            didSomething = true;
        }
    
        updateOnBackPressedCallbackEnabled();
        // 执行延迟启动的Fragment,修改其状态
        doPendingDeferredStart();
        // 这里为了防止列表错误,将mActive的值置为null
        // 而不是在Fragment变为非活动状态的时候将其删除。
        // 但是在执行事务结束时会清理列表
        mFragmentStore.burpActive();
    
        return didSomething;
    }
    

    14.FragmentManager#removeRedundantOperationsAndExecute

    这里的主要目的就是为了移除事务提交过程中,事务列表中冗余的BackStackRecord对象。

    private void removeRedundantOperationsAndExecute(@NonNull ArrayList<BackStackRecord> records,
            @NonNull ArrayList<Boolean> isRecordPop) {
        if (records.isEmpty()) {
            return;
        }
    
        if (records.size() != isRecordPop.size()) {
            throw new IllegalStateException("Internal error with the back stack records");
        }
    
        // 针对与计划处理的事务有交互的任何延迟的事务,进行强制执行
        // 不过这些事务是过去延迟处理,但是当前已经准备好的事务
        executePostponedTransaction(records, isRecordPop);
    
        final int numRecords = records.size();
        int startIndex = 0;
        for (int recordNum = 0; recordNum < numRecords; recordNum++) {
            final boolean canReorder = records.get(recordNum).mReorderingAllowed;
            if (!canReorder) {
                // 执行先前的所有事务
                if (startIndex != recordNum) {
                    executeOpsTogether(records, isRecordPop, startIndex, recordNum);
                }
                // 执行所有不允许重新排序的出栈操作或者事务的添加操作
                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);
        }
    }
    

    15.FragmentManager#executeOpsTogether

    private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records,
            @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
        final boolean allowReordering = records.get(startIndex).mReorderingAllowed;
        boolean addToBackStack = false;
        if (mTmpAddedFragments == null) {
            mTmpAddedFragments = new ArrayList<>();
        } else {
            mTmpAddedFragments.clear();
        }
        mTmpAddedFragments.addAll(mFragmentStore.getFragments());
        Fragment oldPrimaryNav = getPrimaryNavigationFragment();
        for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
            final BackStackRecord record = records.get(recordNum);
            final boolean isPop = isRecordPop.get(recordNum);
            if (!isPop) {
                // 如果是不允许出栈的,修改事务的操作状态
                // 比如将replace的操作也变成了ADD操作
                oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
            } else {
                oldPrimaryNav = record.trackAddedFragmentsInPop(mTmpAddedFragments, oldPrimaryNav);
            }
            addToBackStack = addToBackStack || record.mAddToBackStack;
        }
        mTmpAddedFragments.clear();
    
        if (!allowReordering) {
            FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex,
                    false, mFragmentTransitionCallback);
        }
        // 这里是具体执行对Fragment的add、replace、hide、show等操作的
        executeOps(records, isRecordPop, startIndex, endIndex);
    
        int postponeIndex = endIndex;
        if (allowReordering) {
            ArraySet<Fragment> addedFragments = new ArraySet<>();
            addAddedFragments(addedFragments);
            postponeIndex = postponePostponableTransactions(records, isRecordPop,
                    startIndex, endIndex, addedFragments);
            makeRemovedFragmentsInvisible(addedFragments);
        }
    
        if (postponeIndex != startIndex && allowReordering) {
            // need to run something now
            FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
                    postponeIndex, true, mFragmentTransitionCallback);
            moveToState(mCurState, true);
        }
    
        for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
            final BackStackRecord record = records.get(recordNum);
            final boolean isPop = isRecordPop.get(recordNum);
            if (isPop && record.mIndex >= 0) {
                record.mIndex = -1;
            }
            record.runOnCommitRunnables();
        }
        if (addToBackStack) {
            reportBackStackChanged();
        }
    }
    

    相关文章

      网友评论

          本文标题:Android-Fragment的生命周期处理源码分析

          本文链接:https://www.haomeiwen.com/subject/vgpoyktx.html