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 的生命周期的影响(在 ActivityFragmentManager 生命周期受 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);
        }
    }
}

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

接着看看 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();最后将被销毁的 FragmentActive 列表中移除。

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 的源码阅读就结束了,但是还有很多的功能细节我没有涉及,如果你还感兴趣,就自行去看了,希望我的文章能够帮助到你。

相关推荐
Lei活在当下1 天前
【业务场景架构实战】2. 对聚合支付 SDK 的封装
架构·android jetpack
Tans53 天前
Androidx Fragment 源码阅读笔记(上)
android jetpack·源码阅读
alexhilton5 天前
runBlocking实践:哪里该使用,哪里不该用
android·kotlin·android jetpack
Tans57 天前
Androidx Lifecycle 源码阅读笔记
android·android jetpack·源码阅读
凡小烦7 天前
LeakCanary源码解析
源码阅读·leakcanary
ljt27249606618 天前
Compose笔记(四十九)--SwipeToDismiss
android·笔记·android jetpack
4z3310 天前
Jetpack Compose重组优化:机制剖析与性能提升策略
性能优化·android jetpack
alexhilton11 天前
Android ViewModel数据加载:基于Flow架构的最佳实践
android·kotlin·android jetpack
水牛14 天前
一行代码完成startActivityForResult
android·android jetpack