Análisis de código fuente de procesos de fragmentos

El análisis del código fuente de Fragment y FragmentManager comienza desde dos perspectivas, una es la perspectiva del inicio de la actividad, la otra es la perspectiva del uso normal.

Perspectiva de inicio de actividad

Primero, el inicio de la actividad eventualmente llegará al método performLaunchActivity:

//ActivityThread performLaunchActivity()
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //省略部分代码...
    //step1
    activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
    //step2
    activity.attach(appContext, this, getInstrumentation(), r.token,
            r.ident, app, r.intent, r.activityInfo, title, r.parent,
            r.embeddedID, r.lastNonConfigurationInstances, config,
            r.referrer, r.voiceInteractor, window, r.configCallback,
            r.assistToken, r.shareableActivityToken);


    //step3
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }

    return activity;
}

En el método newActivity del paso 1, la instancia de la actividad se crea mediante la reflexión a través de la información relevante de la actividad, y el método de conexión de la actividad se llama en el paso 2:

FragmentController, FragmentHostCallback

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

final void attach(Context context, ActivityThread aThread,
                  Instrumentation instr, IBinder token, int ident,
                  Application application, Intent intent, ActivityInfo info,
                  CharSequence title, Activity parent, String id,
                  NonConfigurationInstances lastNonConfigurationInstances,
                  Configuration config, String referrer, IVoiceInteractor voiceInteractor,
                  Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
                  IBinder shareableActivityToken) {

    mFragments.attachHost(null /*parent*/);
    
}

Esta es la primera vez que encuentro mFragments. No es un Fragmento. Aunque el nombre es muy similar, es muy intuitivo ver desde el código 1. Una constante de tiempo de ejecución; 2. Por su nombre, se puede ver que esto tiene cierta relación con Fragment. En el método createController, se pasa otro objeto HostCallbacks que hereda de FragmentHostCallback.Echemos un vistazo a esta clase FragmentController:image.png

image.pngSe puede ver a partir de estos códigos que FragmentController es más como una clase de herramienta, solo encapsula algunos métodos, y mFragmentManager logra la implementación final en mHost, y este mFragmentManager es el objeto FragmentManager con el que estamos familiarizados.

image.png

Ahora mire hacia atrás y vea que el método mFragments.attachHost(null) en la actividad eventualmente llegará al método addedController de FragmentManager

image.png image.pngEl mHost y mContainer aquí son la clase interna de actividad HostCallback, y mParent se refiere al Fragmento al que se adjuntará. El proceso actual está impulsado por la actividad, por lo que no hay fragmento y el valor es nulo.

这里我们回顾一下整个流程,1、首先是activity的启动流程会来到performlaunchActivity方法中。2、newActivity方法中通过反射创建activity实例。3从上面的代码可以看出在activity对象创建的过程中,这些mFragments(FragmentController)、mHost(HostCallbacks,继承自FragmentHostCallback)和mFragmentManager对象都会得到创建。而FragmentHostCallback其实可以简单的理解为FragmentManager在Activity(Fragment的宿主)中的回调类,由此还能得出一个结论一个Activity对应了一个FragmentManager

activity onCreate

现在来看一下step3

image.png

image.png

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
//省略部分代码...
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        //step1
        onCreate(icicle);
    }
    //step2
    mFragments.dispatchActivityCreated();
   
}

首先来看一下step1 onCreate

//Activity
protected void onCreate(@Nullable Bundle savedInstanceState) {
    //省略部分代码...
    mFragments.dispatchCreate();
    dispatchActivityCreated(savedInstanceState);

}
//FragmentController
public void dispatchActivityCreated() {
    mHost.mFragmentManager.dispatchActivityCreated();
}

//FragmentManager
void dispatchActivityCreated() {
    mStateSaved = false;
    mStopped = false;
    mNonConfig.setIsStateSaved(false);
    //这里就开始去修改FragmentManager的生命状态了,Fragment.ACTIVITY_CREATED是Fragment的静态变量
    dispatchStateChange(Fragment.ACTIVITY_CREATED);
}
private void dispatchStateChange(int nextState) {
    try {
        mExecutingActions = true;
        mFragmentStore.dispatchStateChange(nextState);
        //去修改FragmentManager的状态
        moveToState(nextState, false);
        if (USE_STATE_MANAGER) {
            Set<SpecialEffectsController> controllers = collectAllSpecialEffectsController();
            for (SpecialEffectsController controller : controllers) {
                controller.forceCompleteAllOperations();
            }
        }
    } finally {
        mExecutingActions = false;
    }
    execPendingActions(true);
}

/**
 * Changes the state of the fragment manager to newState. If the fragment manager changes state or always is true, any fragments within it have their states updated as well.
 * Params:
 * newState – The new state for the fragment manager
 * always – If true, all fragments update their state, even if newState matches the current fragment manager's state.
 */
void moveToState(int newState, boolean always) {
    if (mHost == null && newState != Fragment.INITIALIZING) {
        throw new IllegalStateException("No activity");
    }

    if (!always && newState == mCurState) {
        return;
    }
    //FragmentManager中也维护了一个变量mCurState用于记录当前的生命周期状态
    mCurState = newState;

    if (USE_STATE_MANAGER) {
        mFragmentStore.moveToExpectedState();
    } else {
        // Must add them in the proper order. mActive fragments may be out of order
        for (Fragment f : mFragmentStore.getFragments()) {
            moveFragmentToExpectedState(f);
        }

        // Now iterate through all active fragments. These will include those that are removed
        // and detached.
        for (FragmentStateManager fragmentStateManager :
                mFragmentStore.getActiveFragmentStateManagers()) {
            Fragment f = fragmentStateManager.getFragment();
            if (!f.mIsNewlyAdded) {
                moveFragmentToExpectedState(f);
            }
        }
    }

}


step2其实也就大同小异了不过是把FragmentManager赋值了一个最新的状态。

从mCurState变量可以知道其实FragmentManager也是有生命周期的,它表示的是生命周期当前的状态,在Fragment中也有同样的变量并且它们的初始值都是一样的int mState = INITIALIZING,不同的是Fragment中还有像onCreate、onPause这些生命周期事件

在moveToState中还有一个方法mFragmentStore.moveToExpectedState()它会去修改Fragment的生命周期,后续fragment使用会提到,暂时不用管。

至此activity的初始化时fragment相关的事情就基本结束了,实际上这一套流程走下来基本也就是fragment和fragmentManager生命周期的流程了

Fragment使用视角

下面从我们平常使用的角度去分析Fragment的流程

image.png

supportFragmentManager

supportFragmentManager只在FragmentActivity中,activity中的getFragmentManager已被废弃官方建议使用supportFragmentManager

image.png

image.png

这段代码太简单了,就是上文提到过的直接通过fragmentController返回fragmentHostCallback中的fragmentManager实例对象

beginTransaction

image.png

直接返回一个BackStackRecord实例对象它的父类就是FragmentTransaction,这里先不管它继续往下看

FragmentTransaction、add(R.id.xxx,fragment)

这里就直接拿add来举例了,replace这些都大同小异

FragmentTransaction

//这些常量其实就是对应transaction事务中的add、replace、hide等操作
static final int OP_NULL = 0;
static final int OP_ADD = 1;
static final int OP_REPLACE = 2;
static final int OP_REMOVE = 3;
static final int OP_HIDE = 4;
static final int OP_SHOW = 5;
static final int OP_DETACH = 6;
static final int OP_ATTACH = 7;
static final int OP_SET_PRIMARY_NAV = 8;
static final int OP_UNSET_PRIMARY_NAV = 9;
static final int OP_SET_MAX_LIFECYCLE = 10;

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

//这里的tag参数是fragment的变量,可以通过FragmentManager.findFragmentByTag找对应的fragment
void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
    final Class<?> fragmentClass = fragment.getClass();
    final int modifiers = fragmentClass.getModifiers();
    if (fragmentClass.isAnonymousClass() || !Modifier.isPublic(modifiers)
            || (fragmentClass.isMemberClass() && !Modifier.isStatic(modifiers))) {
        throw new IllegalStateException("Fragment " + fragmentClass.getCanonicalName()
                + " must be a public static class to be  properly recreated from"
                + " instance state.");
    }

    if (tag != null) {
        if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
            throw new IllegalStateException("Can't change tag of fragment "
                    + fragment + ": was " + fragment.mTag
                    + " now " + tag);
        }
        fragment.mTag = tag;
    }

    if (containerViewId != 0) {
        if (containerViewId == View.NO_ID) {
            throw new IllegalArgumentException("Can't add fragment "
                    + fragment + " with tag " + tag + " to container view with no id");
        }
        if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
            throw new IllegalStateException("Can't change container ID of fragment "
                    + fragment + ": was " + fragment.mFragmentId
                    + " now " + containerViewId);
        }
        //step1
        fragment.mContainerId = fragment.mFragmentId = containerViewId;
    }
    
    //step2
    addOp(new Op(opcmd, fragment));
}

这里顺便提一下step1这里给fragment的mContainerId参数赋值了,这里再回到fragmentManager的attachController方法

//之前有提到过第二个参数其实是FragmentActivity中的内部类HostCallbacks对象
//它的父类FragmentHostCallback继承了FragmentContainer
void attachController(@NonNull FragmentHostCallback<?> host,
        @NonNull FragmentContainer container, @Nullable final Fragment parent)
在HostCallbacks中重写了方法

//这里的id实际上就是fragmentManager拿的fragment的mContainerId变量
@Nullable
@Override
public View onFindViewById(int id) {
    return FragmentActivity.this.findViewById(id);
}


addOp

继续看step2 addOp(...)


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

//Op就是FragmentTransaction的静态内部类,它其实就是用来保存fragment及其相关操作信息的
static final class Op {
    int mCmd;
    Fragment mFragment;
    int mEnterAnim;
    int mExitAnim;
    int mPopEnterAnim;
    int mPopExitAnim;
    Lifecycle.State mOldMaxState;
    Lifecycle.State mCurrentMaxState;

    Op() {
    }

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

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

addOp实际上就是把fragment和准备对fragment进行的操作(add、remove等)封装成一个Op对象,再加入到列表中保存,因此FragmentTransaction的主要作用就是设置封装fragment相关操作信息的

commit

事务的封装保存、执行请求

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


int commitInternal(boolean allowStateLoss) {
    //这两行代码印证了一个事务只能提交一次
    if (mCommitted) throw new IllegalStateException("commit already called");
    mCommitted = true;
    
    if (mAddToBackStack) {
        mIndex = mManager.allocBackStackIndex();
    } else {
        mIndex = -1;
    }
    mManager.enqueueAction(this, allowStateLoss);
    return mIndex;
}

//把add操作放入mPendingActions列表中
void enqueueAction(@NonNull OpGenerator action, boolean allowStateLoss) {
    if (!allowStateLoss) {
        if (mHost == null) {
            if (mDestroyed) {
                throw new IllegalStateException("FragmentManager has been destroyed");
            } else {
                throw new IllegalStateException("FragmentManager has not been attached to a "
                        + "host.");
            }
        }
        checkStateLoss();
    }
    //加锁这个mPendingActions保存的就是事务
    synchronized (mPendingActions) {
        if (mHost == null) {
            if (allowStateLoss) {
                // This FragmentManager isn't attached, so drop the entire transaction.
                return;
            }
            throw new IllegalStateException("Activity has been destroyed");
        }
        mPendingActions.add(action);
        scheduleCommit();
    }
}


void scheduleCommit() {
    synchronized (mPendingActions) {
        boolean postponeReady =
                mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
        boolean pendingReady = mPendingActions.size() == 1;
        if (postponeReady || pendingReady) {
            mHost.getHandler().removeCallbacks(mExecCommit);
            //通过handler去发送执行请求
            mHost.getHandler().post(mExecCommit);
            updateOnBackPressedCallbackEnabled();
        }
    }
}


private Runnable mExecCommit = new Runnable() {
    @Override
    public void run() {
        execPendingActions(true);
    }
};

//只在主线程调用,本身我们这里所用的handler其实也就是在主线程创建的
//具体代码可以去FragmentActivity-->HostCallbacks的构造方法中查看
boolean execPendingActions(boolean allowStateLoss) {
    ensureExecReady(allowStateLoss);

    boolean didSomething = false;
    //这里就是把将要执行事务的相关信息保存在mTmpRecords、mTmpIsPop两个列表中
    while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
        mExecutingActions = true;
        try {
            //这里才是真正的执行
            removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
        } finally {
            cleanupExec();
        }
        didSomething = true;
    }

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

    return didSomething;
}


回顾一下当前做了哪些重要的事情:1、创建新的事务BackStackRecord。2、在FragmentTransaction的addOp中去封装fragment、事务的相关操作。3、commit提交执行,首先判断是否重复提交-->是否丢失状态-->把事务放入mPendingActions列表中-->通过handler去发送执行请求-->通过mPendingActions保存的事务把数据保存在mTmpRecords、mTmpIsPop两个列表中-->removeRedundantOperationsAndExecute中真正开始执行

真正的执行

已经删除了部分代码

private void removeRedundantOperationsAndExecute(@NonNull ArrayList<BackStackRecord> records,
        @NonNull ArrayList<Boolean> isRecordPop) {
    final int numRecords = records.size();
    int startIndex = 0;
    for (int recordNum = 0; recordNum < numRecords; recordNum++) {
        final boolean canReorder = records.get(recordNum).mReorderingAllowed;
        //默认是false
        if (!canReorder) {
            // execute all previous transactions
            if (startIndex != recordNum) {
                executeOpsTogether(records, isRecordPop, startIndex, recordNum);
            }
            // execute all pop operations that don't allow reordering together or
            // one add operation
            int reorderingEnd = recordNum + 1;
            if (isRecordPop.get(recordNum)) {
                while (reorderingEnd < numRecords
                        && isRecordPop.get(reorderingEnd)
                        && !records.get(reorderingEnd).mReorderingAllowed) {
                    reorderingEnd++;
                }
            }
            //最终会来到这里
            executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
            startIndex = reorderingEnd;
            recordNum = reorderingEnd - 1;
        }
    }
    if (startIndex != numRecords) {
        executeOpsTogether(records, isRecordPop, startIndex, numRecords);
    }
}


private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records,
                                @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {

    //step1
    FragmentStateManager fragmentStateManager =
        createOrGetFragmentStateManager(fragment);
    //step2
    executeOps(records, isRecordPop, startIndex, endIndex);
    //step3
    fragmentStateManager.moveToExpectedState();
    //step4
    moveToState(mCurState, true);
       
}

来看一下executeOpsTogether中的操作

step1:创建fragmentStateManager并和fragment相关联,这样看起来其实FragmentManager就是包含fragment的生命周期状态,而fragmentStateManager则是管理fragment的生命周期状态。FragmentManager与独立的FragmentStateManager实例进行交互,然后 FragmentStateManager再协调其它Fragment,简化了FragmentManager的逻辑

step2:executeOps方法又回到了BackStackRecord中

//看方法名字就知道这是根据Op封装的不同参数做不同的操作
void executeOps() {
    final int numOps = mOps.size();
    for (int opNum = 0; opNum < numOps; opNum++) {
        final FragmentTransaction.Op op = mOps.get(opNum);
        final Fragment f = op.mFragment;
        if (f != null) {
            f.setPopDirection(false);
            f.setNextTransition(mTransition);
            f.setSharedElementNames(mSharedElementSourceNames, mSharedElementTargetNames);
        }
        switch (op.mCmd) {
            //因为用的是add举例所以这里直接看case OP_ADD
            case OP_ADD:
                //设置fragment进出动画
                f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
                mManager.setExitAnimationOrder(f, false);
                //这里就是通过fragmentManager去addfragment
                mManager.addFragment(f);
                break;
            default:
                throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
        }
    }
}


//最终把fragment保存在ArrayList<Fragment> mAdded列表中
void addFragment(@NonNull Fragment fragment) {
    if (mAdded.contains(fragment)) {
        throw new IllegalStateException("Fragment already added: " + fragment);
    }
    synchronized (mAdded) {
        mAdded.add(fragment);
    }
    fragment.mAdded = true;
}


step3和step4其实最终都会走到fragmentStateManager的moveToExpectedState方法中

//这些方法很明显就和平时所设计到的fragment生命周期回调事件相关了
//来看下create()
while ((newState = computeExpectedState()) != mFragment.mState) {
    if (newState > mFragment.mState) {
        // Moving upward
        int nextStep = mFragment.mState + 1;
        switch (nextStep) {
            case Fragment.ATTACHED:
                attach();
                break;
            case Fragment.CREATED:
                create();
                break;
                
                
void create() {
    if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
        Log.d(TAG, "moveto CREATED: " + mFragment);
    }
    if (!mFragment.mIsCreated) {
        mDispatcher.dispatchOnFragmentPreCreated(
                mFragment, mFragment.mSavedFragmentState, false);
        //fragment的相关回调了
        mFragment.performCreate(mFragment.mSavedFragmentState);
        mDispatcher.dispatchOnFragmentCreated(
                mFragment, mFragment.mSavedFragmentState, false);
    } else {
        mFragment.restoreChildFragmentState(mFragment.mSavedFragmentState);
        mFragment.mState = Fragment.CREATED;
    }
}

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) {
                        mView.cancelPendingInputEvents();
                    }
                }
            }
        });
    }
    mSavedStateRegistryController.performRestore(savedInstanceState);
    //fragment的onCreate回调
    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);
}

Supongo que te gusta

Origin juejin.im/post/7116464721674371085
Recomendado
Clasificación