Androidx Fragment 源码阅读笔记(下)

在上一篇文章中介绍了 Fragment 的状态保存和状态恢复:Androidx Fragment 源码阅读笔记(上)。

本篇文章继续阅读 Fragment 提交事务后,是如何更新我们的 Fragment 状态。

以下先给一个提交事务的 demo:

Kotlin 复制代码
val tc = this@MyFragmentActivity.supportFragmentManager.beginTransaction()
tc.setMaxLifecycle(myFragments[FragmentType.A]!!, Lifecycle.State.CREATED)
tc.commitNowAllowingStateLoss()

先看看 FragmentTransaction 是如何创建的:

Java 复制代码
@NonNull
public FragmentManager getSupportFragmentManager() {
    return mFragments.getSupportFragmentManager();
}

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


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

FragmentTransaction 是一个抽象类,我们使用的实现类是 BackStackRecord。

我们先来看看 FragmentTransaction#setMaxLifecycle() 的实现:

Java 复制代码
@NonNull
public FragmentTransaction setMaxLifecycle(@NonNull Fragment fragment,
        @NonNull Lifecycle.State state) {
    addOp(new Op(OP_SET_MAX_LIFECYCLE, fragment, state));
    return this;
}

void addOp(Op op) {
    mOps.add(op);
    op.mEnterAnim = mEnterAnim;
    op.mExitAnim = mExitAnim;
    op.mPopEnterAnim = mPopEnterAnim;
    op.mPopExitAnim = mPopExitAnim;
}

每当做一个操作就会添加一个 Op 对象到 FragmentTransaction#mOps 成员变量中,操作分为很多种的类型,如下:

Java 复制代码
static final int OP_NULL = 0;
static final int OP_ADD = 1; // 添加 Fragment
static final int OP_REPLACE = 2; // 替换 Container 中的 Fragment,旧的会被移除掉
static final int OP_REMOVE = 3; // 移除 Fragment
static final int OP_HIDE = 4; // 隐藏 Fragment
static final int OP_SHOW = 5; // 显示 Fragment
static final int OP_DETACH = 6; // DETACH Fragment
static final int OP_ATTACH = 7; // ATTACH Fragment
static final int OP_SET_PRIMARY_NAV = 8; // 将 Fragment 设置为 Primary 
static final int OP_UNSET_PRIMARY_NAV = 9; // 将 Fragment 移除为 Primary 
static final int OP_SET_MAX_LIFECYCLE = 10; // 设置 Fragment 的最大周期

关于设置生命周期的 OP 为啥叫设置最大的生命周期,我这里解释一下,因为 Fragment 的生命周期要受 FragmentManager 的生命周期的影响(在 Activity 中 FragmentManager 生命周期受 Activity 的生命周期影响)。假如当 FragmentManager 的生命周期为 Created 的时候,你想要 Fragment 生命周期为 Resume 时就不行,最多也是和 FragmentManager 一样为 Created。只有当 FragmentManager 生命周期到 Resume 后,Fragment 才能够同步到达 Resume。

在开始后面的内容前先说一下 Fragment 还有一种 PopBackStack 的操作方式(可能很多人都没有用过,也不怎么常用):

Kotlin 复制代码
val tc = this@MyFragmentActivity.supportFragmentManager.beginTransaction()
tc.setMaxLifecycle(myFragments[FragmentType.A]!!, Lifecycle.State.CREATED)
tc.setReorderingAllowed(true)
tc.addToBackStack("test_stack")
tc.commitAllowingStateLoss()

当我想要对上面的提交操作,做相反的操作时,比如我上面是设置 Fragment 的生命周期为 CREATED,我想要将 Fragment 生命周期设置为 DESTROYED 时,就只需要调用以下代码:

Kotlin 复制代码
this@MyFragmentActivity.supportFragmentManager.popBackStack()

后面的代码阅读我会跳过 PopBackStack 相关的代码分析。

看看提交事务的 BackStackRecord#commitNowAllowingStateLoss() 方法:

Java 复制代码
@Override
public void commitNowAllowingStateLoss() {
    // commitNowXXX 相关的方法都禁止 BackStack
    disallowAddToBackStack();
    mManager.execSingleAction(this, true);
}

然后继续调用 FragmentManager#execSingleAction() 方法:

Java 复制代码
void execSingleAction(@NonNull OpGenerator action, boolean allowStateLoss) {
    if (allowStateLoss && (mHost == null || mDestroyed)) {
        // This FragmentManager isn't attached, so drop the entire transaction.
        return;
    }
    // 检查执行前的各种状态,也包括是否允许 StateLoss
    ensureExecReady(allowStateLoss);
    // 这个方法会将 Action 自己添加到 mTmpRecords 中,这个 Action 就是 FragmentTransaction
    if (action.generateOps(mTmpRecords, mTmpIsPop)) {
        mExecutingActions = true;
        try {
            // 开始执行 FragmentTransaction
            removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
        } finally {
            cleanupExec();
        }
    }

    updateOnBackPressedCallbackEnabled();
    doPendingDeferredStart();
    mFragmentStore.burpActive();
}

继续看 FragmentManager#removeRedundantOperationsAndExecute() 方法:

Java 复制代码
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");
    }

    final int numRecords = records.size();
    int startIndex = 0;
    for (int recordNum = 0; recordNum < numRecords; recordNum++) {
        final boolean canReorder = records.get(recordNum).mReorderingAllowed;
        if (!canReorder) {
            // ...
            // 执行 Records
            executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
            startIndex = reorderingEnd;
            recordNum = reorderingEnd - 1;
        }
    }
    if (startIndex != numRecords) {
        executeOpsTogether(records, isRecordPop, startIndex, numRecords);
    }
}

继续调用 executeOpsTogether():

Java 复制代码
private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records,
        @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
    
    // ...
    
    
    // 展开 TC 中的 Op
    for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
        final BackStackRecord record = records.get(recordNum);
        final boolean isPop = isRecordPop.get(recordNum);
        if (!isPop) {
            // 展开 TC 中的 Op
            oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
        } else {
            // ...
        }
        // ...
    }
    // ...

    // 确保 Op 中的 Fragment 都在 Active 的列表中
    if (!allowReordering && mCurState >= Fragment.CREATED) {
        // When reordering isn't allowed, we may be operating on Fragments that haven't
        // been made active
        for (int index = startIndex; index < endIndex; index++) {
            BackStackRecord record = records.get(index);
            for (FragmentTransaction.Op op : record.mOps) {
                Fragment fragment = op.mFragment;
                // 确保 Fragment 在 Active 的列表中
                if (fragment != null && fragment.mFragmentManager != null) {
                    FragmentStateManager fragmentStateManager =
                            createOrGetFragmentStateManager(fragment);
                    mFragmentStore.makeActive(fragmentStateManager);
                }
            }
        }
    }
    // 执行 Op 任务,更新各种 Fragment 中的数据
    executeOps(records, isRecordPop, startIndex, endIndex);

    // The last operation determines the overall direction, this ensures that operations
    // such as push, push, pop, push are correctly considered a push
    boolean isPop = isRecordPop.get(endIndex - 1);
    
    // ...
    
    // Ensure that Fragments directly affected by operations
    // are moved to their expected state in operation order
    // 更新 Fragment 的生命周期,和处理一些对应的事情
    for (int index = startIndex; index < endIndex; index++) {
        BackStackRecord record = records.get(index);
        if (isPop) {
            // ...
        } else {
            for (FragmentTransaction.Op op : record.mOps) {
                Fragment fragment = op.mFragment;
                if (fragment != null) {
                    FragmentStateManager fragmentStateManager =
                            createOrGetFragmentStateManager(fragment);
                     // 更新 Fragment 的生命周期,和处理一些对应的事情        
                    fragmentStateManager.moveToExpectedState();
                }
            }
        }

    }
    // And only then do we move all other fragments to the current state
    moveToState(mCurState, true);
    Set<SpecialEffectsController> changedControllers = collectChangedControllers(
            records, startIndex, endIndex);
    // 执行一些特殊任务,像动画什么的        
    for (SpecialEffectsController controller : changedControllers) {
        controller.updateOperationDirection(isPop);
        controller.markPostponedState();
        controller.executePendingOperations();
    }
    
    // ...
}

简单理一下上面的方法做的事情:

  1. 展开 BackStackRecord 中的 Op,调用的方法是 BackStackRecord#expandOps()
  2. 确保 Op 中的 Fragment 都在 Active 的列表中
  3. 通过 executeOps() 方法,执行 Op 任务
  4. 更新 Fragment 的生命周期和处理一些对应的事情,对应的方法是 FragmentStateManager#moveToExpectedState()
  5. 执行特殊任务,比如动画任务

再看看 BackStackRecord#expandOps() 是如何展开 Op 的:

Java 复制代码
@SuppressWarnings("ReferenceEquality")
Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
    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;
                boolean alreadyAdded = false;
                // 查找上次使用这个 containerId 的 Fragment
                for (int i = added.size() - 1; i >= 0; i--) {
                    final Fragment old = added.get(i);
                    if (old.mContainerId == containerId) {
                        if (old == f) { // 上次的 Fragment 和当前 Fragment 是同一个
                            alreadyAdded = true;
                        } else { // 上次 Fragment 和当前的 Fragment 不是同一个
                            // 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, true));
                                opNum++;
                                oldPrimaryNav = null;
                            }
                            // 添加一个 Op 移除上次的 Fragment
                            final Op removeOp = new Op(OP_REMOVE, old, true);
                            removeOp.mEnterAnim = op.mEnterAnim;
                            removeOp.mPopEnterAnim = op.mPopEnterAnim;
                            removeOp.mExitAnim = op.mExitAnim;
                            removeOp.mPopExitAnim = op.mPopExitAnim;
                            mOps.add(opNum, removeOp);
                            added.remove(old);
                            opNum++;
                        }
                    }
                }
                if (alreadyAdded) {
                    // 移除当前的 OP_REPLACE 的 OP
                    mOps.remove(opNum);
                    opNum--;
                } else {
                    // 修改当前的 OP_REPLACE 为 OP_ADD
                    op.mCmd = OP_ADD;
                    op.mFromExpandedOp = true;
                    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, true));
                op.mFromExpandedOp = true;
                opNum++;
                // Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
                oldPrimaryNav = op.mFragment;
            }
            break;
        }
    }
    return oldPrimaryNav;
}

展开 Op 主要干的事情是,当执行 OP_REPLACE 时,会去查找上次这个 ContainerId 所对应的 Fragment,如果找到了就添加一个 OP_REMOVE 去移除这个 Fragment,同时将 OP_REPLACE 修改为 OP_ADD。

继续看 executeOps() 方法:

Java 复制代码
private static void executeOps(@NonNull ArrayList<BackStackRecord> records,
        @NonNull 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) {
            // ...
        } else {
            record.bumpBackStackNesting(1);
            record.executeOps();
        }
    }
}


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.mBeingSaved = mBeingSaved;
            f.setPopDirection(false);
            f.setNextTransition(mTransition);
            f.setSharedElementNames(mSharedElementSourceNames, mSharedElementTargetNames);
        }
        switch (op.mCmd) {
            case OP_ADD:
                f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
                mManager.setExitAnimationOrder(f, false);
                // 将 Fragment 添加到 Active 和 Added 列表中
                mManager.addFragment(f);
                break;
            case OP_REMOVE:
                f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
                // 将 Fragment 从 Added 列表中移除
                mManager.removeFragment(f);
                break;
            case OP_HIDE:
                f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
                // 标记隐藏
                mManager.hideFragment(f);
                break;
            case OP_SHOW:
                f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
                mManager.setExitAnimationOrder(f, false);
                // 标记可见
                mManager.showFragment(f);
                break;
            case OP_DETACH:
                f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
                // 将 Fragment 从 Added 列表中移除,同时标记 detach
                mManager.detachFragment(f);
                break;
            case OP_ATTACH:
             
                f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
                mManager.setExitAnimationOrder(f, false);
                // 将 Fragment 添加到 Added 列表中,同时标记 attach
                mManager.attachFragment(f);
                break;
            case OP_SET_PRIMARY_NAV:
                mManager.setPrimaryNavigationFragment(f);
                break;
            case OP_UNSET_PRIMARY_NAV:
                mManager.setPrimaryNavigationFragment(null);
                break;
            case OP_SET_MAX_LIFECYCLE:
                // 更新最大的生命周期
                mManager.setMaxLifecycle(f, op.mCurrentMaxState);
                break;
            default:
                throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
        }
    }
}

上面的代码都很简单,就是简单更新 Added 和 Active 两个列表,和一些简单的数据。

接着看看 FragmentStateManager#moveToExpectedState() 方法,这个方法就涉及到 Fragment 的状态更新和生命周期方法的回调了。

Java 复制代码
void moveToExpectedState() {
    if (mMovingToState) {
        if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
            Log.v(FragmentManager.TAG, "Ignoring re-entrant call to "
                    + "moveToExpectedState() for " + getFragment());
        }
        return;
    }
    try {
        mMovingToState = true;

        boolean stateWasChanged = false;
        int newState;
        // 计算本次循环的 Fragment 的期望的状态,如果不等于当前状态,执行循环
        while ((newState = computeExpectedState()) != mFragment.mState) {
            stateWasChanged = true;
            if (newState > mFragment.mState) { // 生命周期向前更新,比如 Created -> Started
                // Moving upward
                int nextStep = mFragment.mState + 1;
                switch (nextStep) {
                    case Fragment.ATTACHED:
                        attach();
                        break;
                    case Fragment.CREATED:
                        create();
                        break;
                    case Fragment.VIEW_CREATED:
                        ensureInflatedView();
                        createView();
                        break;
                    case Fragment.AWAITING_EXIT_EFFECTS:
                        activityCreated();
                        break;
                    case Fragment.ACTIVITY_CREATED:
                        if (mFragment.mView != null && mFragment.mContainer != null) {
                            SpecialEffectsController controller = SpecialEffectsController
                                    .getOrCreateController(mFragment.mContainer,
                                            mFragment.getParentFragmentManager());
                            int visibility = mFragment.mView.getVisibility();
                            SpecialEffectsController.Operation.State finalState =
                                    SpecialEffectsController.Operation.State.from(visibility);
                            controller.enqueueAdd(finalState, this);
                        }
                        mFragment.mState = Fragment.ACTIVITY_CREATED;
                        break;
                    case Fragment.STARTED:
                        start();
                        break;
                    case Fragment.AWAITING_ENTER_EFFECTS:
                        mFragment.mState = Fragment.AWAITING_ENTER_EFFECTS;
                        break;
                    case Fragment.RESUMED:
                        resume();
                        break;
                }
            } else { // 生命周期向后更新,比如 Started -> Created
                // Moving downward
                int nextStep = mFragment.mState - 1;
                switch (nextStep) {
                    case Fragment.AWAITING_ENTER_EFFECTS:
                        pause();
                        break;
                    case Fragment.STARTED:
                        mFragment.mState = Fragment.STARTED;
                        break;
                    case Fragment.ACTIVITY_CREATED:
                        stop();
                        break;
                    case Fragment.AWAITING_EXIT_EFFECTS:
                        if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
                            Log.d(TAG, "movefrom ACTIVITY_CREATED: " + mFragment);
                        }
                        if (mFragment.mBeingSaved) {
                            mFragmentStore.setSavedState(mFragment.mWho, saveState());
                        } else if (mFragment.mView != null) {
                            // Need to save the current view state if not done already
                            // by saveInstanceState()
                            if (mFragment.mSavedViewState == null) {
                                saveViewState();
                            }
                        }
                        if (mFragment.mView != null && mFragment.mContainer != null) {
                            SpecialEffectsController controller = SpecialEffectsController
                                    .getOrCreateController(mFragment.mContainer,
                                            mFragment.getParentFragmentManager());
                            controller.enqueueRemove(this);
                        }
                        mFragment.mState = Fragment.AWAITING_EXIT_EFFECTS;
                        break;
                    case Fragment.VIEW_CREATED:
                        mFragment.mInLayout = false;
                        mFragment.mState = Fragment.VIEW_CREATED;
                        break;
                    case Fragment.CREATED:
                        destroyFragmentView();
                        mFragment.mState = Fragment.CREATED;
                        break;
                    case Fragment.ATTACHED:
                        if (mFragment.mBeingSaved
                                && mFragmentStore.getSavedState(mFragment.mWho) == null) {
                            mFragmentStore.setSavedState(mFragment.mWho, saveState());
                        }
                        destroy();
                        break;
                    case Fragment.INITIALIZING:
                        detach();
                        break;
                }
            }
        }
        // ...
    } finally {
        mMovingToState = false;
    }
}

在上面的方法中会通过 computeExpectedState() 方法去计算下次 Fragment 应该执行的生命周期状态,比如 FragmentManager 的状态是 RESUMED,当前 Fragment 的 状态是 ATTACHED,同时 Fragment 的最大生命周期状态是 RESUMED,那么在循环中 Fragment 的生命周期状态会依次更新:CREATED -> VIEW_CREATED -> ACTIVITY_CREATED -> STARTED -> RESUME。并执行相关 Fragment 的生命周期回调。

我上面的例子举的是生命周期变大的例子,当然也有生命周期变小的例子。

我们也根据生命周期变大和变小分别来看他们的状态更新。

生命周期变大

ATTACHED

FragmentStateManager#attach():

Java 复制代码
void attach() {
    // ...
    
    mFragment.mHost = mFragment.mFragmentManager.getHost();
    mFragment.mParentFragment = mFragment.mFragmentManager.getParent();
    mDispatcher.dispatchOnFragmentPreAttached(mFragment, false);
    mFragment.performAttach();
    mDispatcher.dispatchOnFragmentAttached(mFragment, false);
}

Fragment#performAttach():

Java 复制代码
void performAttach() {
    for (OnPreAttachedListener listener: mOnPreAttachedListeners) {
        listener.onPreAttached();
    }
    mOnPreAttachedListeners.clear();
    mChildFragmentManager.attachController(mHost, createFragmentContainer(), this);
    mState = ATTACHED;
    mCalled = false;
    // 回调生命周期
    onAttach(mHost.getContext());
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onAttach()");
    }
    mFragmentManager.dispatchOnAttachFragment(this);
    mChildFragmentManager.dispatchAttach();
}

CREATED

FragmentManager#create():

Java 复制代码
void create() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "moveto CREATED: " + mFragment);
    }
    Bundle savedInstanceState = null;
    if (mFragment.mSavedFragmentState != null) {
        savedInstanceState = mFragment.mSavedFragmentState.getBundle(SAVED_INSTANCE_STATE_KEY);
    }
    if (!mFragment.mIsCreated) {
        mDispatcher.dispatchOnFragmentPreCreated(mFragment, savedInstanceState, false);
        mFragment.performCreate(savedInstanceState);
        mDispatcher.dispatchOnFragmentCreated(mFragment, savedInstanceState, false);
    } else {
        // ...
    }
}

Fragment#performCreate():

Java 复制代码
void performCreate(Bundle savedInstanceState) {
    mChildFragmentManager.noteStateNotSaved();
    mState = CREATED;
    mCalled = false;
    if (Build.VERSION.SDK_INT >= 19) {
        mLifecycleRegistry.addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_STOP) {
                    if (mView != null) {
                        Api19Impl.cancelPendingInputEvents(mView);
                    }
                }
            }
        });
    }
    // 生命周期回调
    onCreate(savedInstanceState);
    mIsCreated = true;
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onCreate()");
    }
    // 更新 Lifecycle 生命周期事件
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}

VIEW_CREATED

FragmentStateManager#createView():

Java 复制代码
void createView() {
    if (mFragment.mFromLayout) {
        // This case is handled by ensureInflatedView(), so there's nothing
        // else we need to do here.
        return;
    }
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "moveto CREATE_VIEW: " + mFragment);
    }
    Bundle savedInstanceState = null;
    if (mFragment.mSavedFragmentState != null) {
        savedInstanceState = mFragment.mSavedFragmentState.getBundle(SAVED_INSTANCE_STATE_KEY);
    }
    LayoutInflater layoutInflater = mFragment.performGetLayoutInflater(savedInstanceState);
    ViewGroup container = null;
    // 根据 containerId 找到对应的 ContainerView
    if (mFragment.mContainer != null) {
        container = mFragment.mContainer;
    } else if (mFragment.mContainerId != 0) {
        if (mFragment.mContainerId == View.NO_ID) {
            throw new IllegalArgumentException("Cannot create fragment " + mFragment
                    + " for a container view with no id");
        }
        FragmentContainer fragmentContainer = mFragment.mFragmentManager.getContainer();
        container = (ViewGroup) fragmentContainer.onFindViewById(mFragment.mContainerId);
        if (container == null) {
            if (!mFragment.mRestored) {
                String resName;
                try {
                    resName = mFragment.getResources().getResourceName(mFragment.mContainerId);
                } catch (Resources.NotFoundException e) {
                    resName = "unknown";
                }
                throw new IllegalArgumentException("No view found for id 0x"
                        + Integer.toHexString(mFragment.mContainerId) + " ("
                        + resName + ") for fragment " + mFragment);
            }
        } else {
            if (!(container instanceof FragmentContainerView)) {
                FragmentStrictMode.onWrongFragmentContainer(mFragment, container);
            }
        }
    }
    mFragment.mContainer = container;
    // 执行 onCreateView() 生命周期
    mFragment.performCreateView(layoutInflater, container, savedInstanceState);
    if (mFragment.mView != null) { // 如果创建的 view 不为空
        if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
            Log.d(TAG, "moveto VIEW_CREATED: " + mFragment);
        }
        mFragment.mView.setSaveFromParentEnabled(false);
        // 将 Fragment 设置 tag 到 view 中
        mFragment.mView.setTag(R.id.fragment_container_view_tag, mFragment);
        if (container != null) {
            // 将 view 添加到 container 中
            addViewToContainer();
        }
        // 更新可见
        if (mFragment.mHidden) {
            mFragment.mView.setVisibility(View.GONE);
        }
        // How I wish we could use doOnAttach
        if (ViewCompat.isAttachedToWindow(mFragment.mView)) {
            ViewCompat.requestApplyInsets(mFragment.mView);
        } else {
            final View fragmentView = mFragment.mView;
            fragmentView.addOnAttachStateChangeListener(
                    new View.OnAttachStateChangeListener() {
                        @Override
                        public void onViewAttachedToWindow(View v) {
                            fragmentView.removeOnAttachStateChangeListener(this);
                            ViewCompat.requestApplyInsets(fragmentView);
                        }

                        @Override
                        public void onViewDetachedFromWindow(View v) {
                        }
                    });
        }
        // 触发 onViewCreated() 生命周期回调
        mFragment.performViewCreated();
        mDispatcher.dispatchOnFragmentViewCreated(
                mFragment, mFragment.mView, savedInstanceState, false);
        int postOnViewCreatedVisibility = mFragment.mView.getVisibility();
        float postOnViewCreatedAlpha = mFragment.mView.getAlpha();
        mFragment.setPostOnViewCreatedAlpha(postOnViewCreatedAlpha);
        if (mFragment.mContainer != null && postOnViewCreatedVisibility == View.VISIBLE) {
            // Save the focused view if one was set via requestFocus()
            View focusedView = mFragment.mView.findFocus();
            if (focusedView != null) {
                mFragment.setFocusedView(focusedView);
                if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
                    Log.v(TAG, "requestFocus: Saved focused view " + focusedView
                            + " for Fragment " + mFragment);
                }
            }
            // Set the view alpha to 0
            mFragment.mView.setAlpha(0f);
        }
    }
    mFragment.mState = Fragment.VIEW_CREATED;
}

创建 View 的方法要稍微复杂一点点,首先通过 containerId 找到其对应的 containerView;然后触发 Fragment#performCreateView() 方法创建 view;将创建的 view 添加到 containerView 中;触发 Fragment#performViewCreated()。

Fragment#performCreateView():

Java 复制代码
void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
        @Nullable Bundle savedInstanceState) {
    mChildFragmentManager.noteStateNotSaved();
    mPerformedCreateView = true;
    mViewLifecycleOwner = new FragmentViewLifecycleOwner(this, getViewModelStore(),
            () -> {
                // Perform the restore as soon as the FragmentViewLifecycleOwner
                // becomes initialized, to ensure it is always available
                mViewLifecycleOwner.performRestore(mSavedViewRegistryState);
                mSavedViewRegistryState = null;
            });
    // 触发生命周期创建 view        
    mView = onCreateView(inflater, container, savedInstanceState);
    if (mView != null) {
        // Initialize the view lifecycle
        mViewLifecycleOwner.initialize();
        // Tell the fragment's new view about it before we tell anyone listening
        // to mViewLifecycleOwnerLiveData and before onViewCreated, so that calls to
        // ViewTree get() methods return something meaningful
        if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
            Log.d(FragmentManager.TAG, "Setting ViewLifecycleOwner on View " + mView
                    + " for Fragment " + this);
        }
        ViewTreeLifecycleOwner.set(mView, mViewLifecycleOwner);
        ViewTreeViewModelStoreOwner.set(mView, mViewLifecycleOwner);
        ViewTreeSavedStateRegistryOwner.set(mView, mViewLifecycleOwner);
        // Then inform any Observers of the new LifecycleOwner
        mViewLifecycleOwnerLiveData.setValue(mViewLifecycleOwner);
    } else {
        if (mViewLifecycleOwner.isInitialized()) {
            throw new IllegalStateException("Called getViewLifecycleOwner() but "
                    + "onCreateView() returned null");
        }
        mViewLifecycleOwner = null;
    }
}

Fragment#performViewCreated():

Java 复制代码
void performViewCreated() {
    // since calling super.onViewCreated() is not required, we do not need to set and check the
    // `mCalled` flag
    Bundle savedInstanceState = null;
    if (mSavedFragmentState != null) {
        savedInstanceState = mSavedFragmentState.getBundle(
                FragmentStateManager.SAVED_INSTANCE_STATE_KEY);
    }
    onViewCreated(mView, savedInstanceState);
    mChildFragmentManager.dispatchViewCreated();
}

AWAITING_EXIT_EFFECTS

FragmentStateManager#activityCreated():

Java 复制代码
void activityCreated() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "moveto ACTIVITY_CREATED: " + mFragment);
    }
    Bundle savedInstanceState = null;
    if (mFragment.mSavedFragmentState != null) {
        savedInstanceState = mFragment.mSavedFragmentState.getBundle(SAVED_INSTANCE_STATE_KEY);
    }
    mFragment.performActivityCreated(savedInstanceState);
    mDispatcher.dispatchOnFragmentActivityCreated(
            mFragment, savedInstanceState, false);
}

Fragment#performActivityCreated():

Java 复制代码
void performActivityCreated(Bundle savedInstanceState) {
    mChildFragmentManager.noteStateNotSaved();
    mState = AWAITING_EXIT_EFFECTS;
    mCalled = false;
    onActivityCreated(savedInstanceState);
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onActivityCreated()");
    }
    restoreViewState();
    mChildFragmentManager.dispatchActivityCreated();
}

STARTED

FragmentStateManager#start():

Java 复制代码
void start() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "moveto STARTED: " + mFragment);
    }
    mFragment.performStart();
    mDispatcher.dispatchOnFragmentStarted(mFragment, false);
}

Fragment#performStart():

Java 复制代码
void performStart() {
    mChildFragmentManager.noteStateNotSaved();
    mChildFragmentManager.execPendingActions(true);
    mState = STARTED;
    mCalled = false;
    onStart();
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onStart()");
    }
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    if (mView != null) {
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }
    mChildFragmentManager.dispatchStart();
}

RESUMED

FragmentStateManager#resume():

Java 复制代码
void resume() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "moveto RESUMED: " + mFragment);
    }
    View focusedView = mFragment.getFocusedView();
    if (focusedView != null && isFragmentViewChild(focusedView)) {
        boolean success = focusedView.requestFocus();
        if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
            Log.v(FragmentManager.TAG, "requestFocus: Restoring focused view "
                    + focusedView + " " + (success ? "succeeded" : "failed") + " on Fragment "
                    + mFragment + " resulting in focused view " + mFragment.mView.findFocus());
        }
    }
    mFragment.setFocusedView(null);
    mFragment.performResume();
    mDispatcher.dispatchOnFragmentResumed(mFragment, false);
    mFragmentStore.setSavedState(mFragment.mWho, null);
    mFragment.mSavedFragmentState = null;
    mFragment.mSavedViewState = null;
    mFragment.mSavedViewRegistryState = null;
}

Fragment#performResume():

Java 复制代码
void performResume() {
    mChildFragmentManager.noteStateNotSaved();
    mChildFragmentManager.execPendingActions(true);
    mState = RESUMED;
    mCalled = false;
    onResume();
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onResume()");
    }
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    if (mView != null) {
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }
    mChildFragmentManager.dispatchResume();
}

生命周期变小

AWAITING_ENTER_EFFECTS

FragmentStateManager#pause():

Java 复制代码
void pause() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "movefrom RESUMED: " + mFragment);
    }
    mFragment.performPause();
    mDispatcher.dispatchOnFragmentPaused(mFragment, false);
}

Fragment#performPause():

Java 复制代码
void performPause() {
    mChildFragmentManager.dispatchPause();
    if (mView != null) {
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
    }
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
    mState = AWAITING_ENTER_EFFECTS;
    mCalled = false;
    onPause();
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onPause()");
    }
}

ACTIVITY_CREATED

FragmentManagerState#stop():

Java 复制代码
void stop() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "movefrom STARTED: " + mFragment);
    }
    mFragment.performStop();
    mDispatcher.dispatchOnFragmentStopped(mFragment, false);
}

Fragment#performStop():

Java 复制代码
void performStop() {
    mChildFragmentManager.dispatchStop();
    if (mView != null) {
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    }
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    mState = ACTIVITY_CREATED;
    mCalled = false;
    onStop();
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onStop()");
    }
}

CREATED

FragmentStateManager#destroyFragmentView():

Java 复制代码
void destroyFragmentView() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "movefrom CREATE_VIEW: " + mFragment);
    }
    // In cases where we never got up to AWAITING_EXIT_EFFECTS, we
    // need to manually remove the view from the container to reverse
    // what we did in createView()
    // 从 container 中移除 view
    if (mFragment.mContainer != null && mFragment.mView != null) {
        mFragment.mContainer.removeView(mFragment.mView);
    }
    mFragment.performDestroyView();
    mDispatcher.dispatchOnFragmentViewDestroyed(mFragment, false);
    mFragment.mContainer = null;
    mFragment.mView = null;
    // Set here to ensure that Observers are called after
    // the Fragment's view is set to null
    mFragment.mViewLifecycleOwner = null;
    mFragment.mViewLifecycleOwnerLiveData.setValue(null);
    mFragment.mInLayout = false;
}

Fragment#performDestoryView():

Java 复制代码
void performDestroyView() {
    mChildFragmentManager.dispatchDestroyView();
    if (mView != null && mViewLifecycleOwner.getLifecycle().getCurrentState()
                    .isAtLeast(Lifecycle.State.CREATED)) {
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    }
    mState = CREATED;
    mCalled = false;
    onDestroyView();
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onDestroyView()");
    }
    // Handles the detach/reattach case where the view hierarchy
    // is destroyed and recreated and an additional call to
    // onLoadFinished may be needed to ensure the new view
    // hierarchy is populated from data from the Loaders
    LoaderManager.getInstance(this).markForRedelivery();
    mPerformedCreateView = false;
}

ATTACHED

FragmentStateManager#destroy():

Java 复制代码
void destroy() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "movefrom CREATED: " + mFragment);
    }
    boolean beingRemoved = mFragment.mRemoving && !mFragment.isInBackStack();
    // Clear any previous saved state
    if (beingRemoved && !mFragment.mBeingSaved) {
        mFragmentStore.setSavedState(mFragment.mWho, null);
    }
    boolean shouldDestroy = beingRemoved
            || mFragmentStore.getNonConfig().shouldDestroy(mFragment);
    if (shouldDestroy) {
        FragmentHostCallback<?> host = mFragment.mHost;
        boolean shouldClear;
        if (host instanceof ViewModelStoreOwner) {
            shouldClear = mFragmentStore.getNonConfig().isCleared();
        } else if (host.getContext() instanceof Activity) {
            Activity activity = (Activity) host.getContext();
            shouldClear = !activity.isChangingConfigurations();
        } else {
            shouldClear = true;
        }
        if ((beingRemoved && !mFragment.mBeingSaved) || shouldClear) {
            // 移除 Fragment 中的 ViewModelStore
            mFragmentStore.getNonConfig().clearNonConfigState(mFragment);
        }
        // 销毁
        mFragment.performDestroy();
        mDispatcher.dispatchOnFragmentDestroyed(mFragment, false);
        // Ensure that any Fragment that had this Fragment as its
        // target Fragment retains a reference to the Fragment
        for (FragmentStateManager fragmentStateManager :
                mFragmentStore.getActiveFragmentStateManagers()) {
            if (fragmentStateManager != null) {
                Fragment fragment = fragmentStateManager.getFragment();
                if (mFragment.mWho.equals(fragment.mTargetWho)) {
                    fragment.mTarget = mFragment;
                    fragment.mTargetWho = null;
                }
            }
        }
        if (mFragment.mTargetWho != null) {
            // Restore the target Fragment so that it can be accessed
            // even after the Fragment is removed.
            mFragment.mTarget = mFragmentStore.findActiveFragment(mFragment.mTargetWho);
        }
        // 将 Fragment 从 Attach 列表中移除
        mFragmentStore.makeInactive(this);
    } else {
        if (mFragment.mTargetWho != null) {
            Fragment target = mFragmentStore.findActiveFragment(mFragment.mTargetWho);
            if (target != null && target.mRetainInstance) {
                // Only keep references to other retained Fragments
                // to avoid developers accessing Fragments that
                // are never coming back
                mFragment.mTarget = target;
            }
        }
        mFragment.mState = Fragment.ATTACHED;
    }
}

上面代码中首先将 Fragment 中的 ViewModelStore 移除,还包括其他的 NonConfig 数据;然后回调 Fragment#performDestroy();最后将被销毁的 Fragment 从 Active 列表中移除。

Fragment#performDestroy():

Java 复制代码
void performDestroy() {
    mChildFragmentManager.dispatchDestroy();
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    mState = ATTACHED;
    mCalled = false;
    mIsCreated = false;
    onDestroy();
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onDestroy()");
    }
}

INITIALIZING

FragmentStateManager#detach():

Java 复制代码
void detach() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "movefrom ATTACHED: " + mFragment);
    }
    mFragment.performDetach();
    mDispatcher.dispatchOnFragmentDetached(
            mFragment, false);
    mFragment.mState = Fragment.INITIALIZING;
    mFragment.mHost = null;
    mFragment.mParentFragment = null;
    mFragment.mFragmentManager = null;
    boolean beingRemoved = mFragment.mRemoving && !mFragment.isInBackStack();
    if (beingRemoved || mFragmentStore.getNonConfig().shouldDestroy(mFragment)) {
        if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
            Log.d(TAG, "initState called for fragment: " + mFragment);
        }
        mFragment.initState();
    }
}

Fragment#performDetach():

Java 复制代码
void performDetach() {
    mState = INITIALIZING;
    mCalled = false;
    onDetach();
    mLayoutInflater = null;
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onDetach()");
    }

    // Destroy the child FragmentManager if we still have it here.
    // This is normally done in performDestroy(), but is done here
    // specifically if the Fragment is retained.
    // 销毁并清空 FragmentManager
    if (!mChildFragmentManager.isDestroyed()) {
        mChildFragmentManager.dispatchDestroy();
        mChildFragmentManager = new FragmentManagerImpl();
    }
}

最后

到这里我的 Fragment 的源码阅读就结束了,但是还有很多的功能细节我没有涉及,如果你还感兴趣,就自行去看了,希望我的文章能够帮助到你。

相关推荐
用户094248568031 天前
Redis 实战修炼与原理进阶专栏大纲
redis·快应用·源码阅读
hai_android1 天前
LiveEventBusCore 跨 Activity 通讯源码解析
android·kotlin·android jetpack
RobinXYuan1 天前
【Kafka 源码手记】02 Kafka 的核心哲学:Everything Is A Log
kafka·源码阅读
麦客奥德彪2 天前
别把 Agent 写成一个大循环:读懂 DeepSeek Harness 的接口与运行时设计
agent·源码阅读
RobinXYuan3 天前
【LevelDB 源码阅读】06 | WAL:日志的物理格式
源码阅读·leveldb
我命由我123454 天前
Android 广播 - 组件通信
android·java·开发语言·android studio·android jetpack·android-studio·android runtime
嘎嘎风4 天前
MiniMind 学习笔记之 21 训练细节:数据、分词器、断点续训
gpt·源码阅读
RobinXYuan4 天前
【Kafka 源码手记】01 从消息队列到 Event Streaming
kafka·源码阅读
alexhilton5 天前
为什么你的 LazyColumn 仍然卡顿
android·kotlin·android jetpack
hai_android5 天前
Android 嵌套滑动冲突:内部拦截 vs 外部拦截实战
android·android studio·android jetpack