组件之Fragment源码解析

一、Framgnet源码解析

(1)getSupportFragmentManager()源码

  • mHost.mFragmentManager获取的是FragmentMananger的实现类FragmentManagerImpl。
    @NonNull
    public FragmentManager getSupportFragmentManager() {
        return mFragments.getSupportFragmentManager();
    }

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

(2)FragmentManagerImpl.beginTransaction()源码

  • new BackStackRecord(this)获取的是FragmentTransaction的实现类BackStackRecord(事务管理器)。
    @NonNull
    @Override
    public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
    }

(3)FragmentTransaction.add()源码

  • 在add方法中,系统只做了赋值操作,并没有对Fragment进行任何操作。
  • opcmd标记是什么类型的操作
  • 将fragment等信息追加到ArrayList列表的末尾。
    @NonNull
    public FragmentTransaction add(@NonNull Fragment fragment, @Nullable String tag)  {
        doAddOp(0, fragment, tag, OP_ADD);
        return this;
    }

    @NonNull
    public FragmentTransaction add(@IdRes int containerViewId, @NonNull Fragment fragment) {
        doAddOp(containerViewId, fragment, null, OP_ADD);
        return this;
    }

    @NonNull
    public FragmentTransaction add(@IdRes int containerViewId, @NonNull Fragment fragment, @Nullable String tag) {
        doAddOp(containerViewId, fragment, tag, OP_ADD);
        return this;
    }

    //BackStackRecord.java
    @Override
    void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
        super.doAddOp(containerViewId, fragment, tag, opcmd);
        fragment.mFragmentManager = mManager;
    }

    void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
        //code...
        addOp(new Op(opcmd, fragment));
    }

        Op(int cmd, Fragment fragment) {
            this.mCmd = cmd;
            this.mFragment = fragment;
            this.mOldMaxState = Lifecycle.State.RESUMED;
            this.mCurrentMaxState = Lifecycle.State.RESUMED;
        }

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

(4)BackStackRecord.commit源码

    @Override
    public int commit() {
        return commitInternal(false);
    }

    int commitInternal(boolean allowStateLoss) {
        //code..
        if (mAddToBackStack) {
            mIndex = mManager.allocBackStackIndex(this);
        } else {
            mIndex = -1;
        }
        mManager.enqueueAction(this, allowStateLoss);
        return mIndex;
    }
  • mManager.allocBackStackIndex(this):将BackStackRecord添加到mBackStackIndices中。
    public int allocBackStackIndex(BackStackRecord bse) {
        synchronized (this) {
            if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) {
                if (mBackStackIndices == null) {
                    mBackStackIndices = new ArrayList();
                }
                int index = mBackStackIndices.size();
                mBackStackIndices.add(bse);
                return index;

            } else {
                int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1);
                mBackStackIndices.set(index, bse);
                return index;
            }
        }
    }
  • mManager.enqueueAction(this, allowStateLoss):将实现OpGenerator的BackStackRecord添加到了mPendingActions。
    public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
        //code..
        synchronized (this) {
            //code..
            mPendingActions.add(action);
            scheduleCommit();
        }
    }
    
    //调用handler
    void scheduleCommit() {
        synchronized (this) {
            boolean postponeReady =
                    mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
            boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
            if (postponeReady || pendingReady) {
                mHost.getHandler().removeCallbacks(mExecCommit);
                mHost.getHandler().post(mExecCommit);
                updateOnBackPressedCallbackEnabled();
            }
        }
    }
  • FragmentManagerImpl.mExecCommit源码
    Runnable mExecCommit = new Runnable() {
        @Override
        public void run() {
            execPendingActions();
        }
    };

    public boolean execPendingActions() {
        ensureExecReady(true);
        boolean didSomething = false;
        while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
            mExecutingActions = true;
            try {
                removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
            } finally {
                cleanupExec();
            }
            didSomething = true;
        }
        updateOnBackPressedCallbackEnabled();
        doPendingDeferredStart();
        burpActive();
        return didSomething;
    }
  • generateOpsForPendingActions(mTmpRecords, mTmpIsPop):将mPendingActions数据添加到mTmpRecords,赋值mTmpIsPop值为false,清空mPendingActions数据并删除handler中的mExecCommit
    private boolean generateOpsForPendingActions(ArrayList records, ArrayList isPop) {
        boolean didSomething = false;
        synchronized (this) {
            final int numActions = mPendingActions.size();
            for (int i = 0; i < numActions; i++) {
                didSomething |= mPendingActions.get(i).generateOps(records, isPop);
            }
            mPendingActions.clear();
            mHost.getHandler().removeCallbacks(mExecCommit);
        }
        return didSomething;
    }

    @Override
    public boolean generateOps(ArrayList records, ArrayList isRecordPop) {
        records.add(this);
        isRecordPop.add(false);
        if (mAddToBackStack) {
            mManager.addBackStackState(this);
        }
        return true;
    }
  • removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop):通过调用executeOpsTogether方法来执行添加的所有任务。
  • 在moveToState方法中调用FragmentManager中dispatchxxx方法。而这些正好是和activity的生命周期对应起来,也就是说这些方法是随着activity进入到不同的生命周期而被调用的,即mCurState的值是被这些方法触发设置的。
    private void removeRedundantOperationsAndExecute(ArrayList records, ArrayList isRecordPop) {
        //code...
        final int numRecords = records.size();
        int startIndex = 0;
        for (int recordNum = 0; recordNum < numRecords; recordNum++) {
                //code...
                int reorderingEnd = recordNum + 1;
                //code...
                executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
                startIndex = reorderingEnd;
                recordNum = reorderingEnd - 1;
        }
        //code...
    }

    //执行添加的所有任务
    private void executeOpsTogether(ArrayList records, ArrayList isRecordPop, int startIndex, int endIndex) {
        //code...
        executeOps(records, isRecordPop, startIndex, endIndex);
        //code...
    }

    //入栈或者出栈操作
    private static void executeOps(ArrayList records, ArrayList isRecordPop, int startIndex, int endIndex) {
        for (int i = startIndex; i < endIndex; i++) {
            final BackStackRecord record = records.get(i);
            //默认存储为false
            final boolean isPop = isRecordPop.get(i);
            if (isPop) {
                record.bumpBackStackNesting(-1);
                boolean moveToState = i == (endIndex - 1);
                record.executePopOps(moveToState);
            } 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.fragment;
            if (f != null) {
                f.setNextTransition(mTransition, mTransitionStyle);
            }
            switch (op.cmd) {
                case OP_ADD:
                    f.setNextAnim(op.enterAnim);
                    mManager.addFragment(f, false);
                    break;
                case OP_REMOVE:
                    f.setNextAnim(op.exitAnim);
                    mManager.removeFragment(f);
                    break;
                case OP_HIDE:
                    f.setNextAnim(op.exitAnim);
                    mManager.hideFragment(f);
                    break;
                case OP_SHOW:
                    f.setNextAnim(op.enterAnim);
                    mManager.showFragment(f);
                    break;
                case OP_DETACH:
                    f.setNextAnim(op.exitAnim);
                    mManager.detachFragment(f);
                    break;
                case OP_ATTACH:
                    f.setNextAnim(op.enterAnim);
                    mManager.attachFragment(f);
                    break;
                case OP_SET_PRIMARY_NAV:
                    mManager.setPrimaryNavigationFragment(f);
                    break;
                case OP_UNSET_PRIMARY_NAV:
                    mManager.setPrimaryNavigationFragment(null);
                    break;
                default:
                    throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
            }
            if (!mReorderingAllowed && op.cmd != OP_ADD && f != null) {
                mManager.moveFragmentToExpectedState(f);
            }
        }
        if (!mReorderingAllowed) {
            mManager.moveToState(mManager.mCurState, true);
        }
    }

总结

  • 通过源码得知add、remove、replacea、hide、show等方法中只是做了赋值操作,并没有对Fragment进行任何操作。
  • commit()将FragmentTransaction的实现类BackStackRecord添加到mBackStackIndices集合中。
  • 通过enqueueAction()方法将实现OpGenerator的BackStackRecord添加到了mPendingActions中,并通过scheduleCommit方法调用handler.post(mExecCommit)。
  • mExecCommit是一个Runnable对象,在run方法中调用execPendingActions()方法。
  • execPendingActions()方法将mPendingActions中数据添加到mTmpRecords中,并将mTmpIsPop赋值为false,清空mPendingActions数据并删除handler中mExecCommit对象;通过调用executeOpsTogether方法来执行添加的所有任务。

你可能感兴趣的:(组件之Fragment源码解析)