从源码角度分析Fragment生命周期流程

1,579 阅读7分钟

对于Fragment、FragmentManager的源码分析从两个角度出发,一个是activity启动时的角度,一个是平时使用时的角度

Activity启动视角

首先activity的启动最终会来到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;
}

在step1的newActivity方法中通过activity的相关信息用反射的方式创建了activity实例,在step2中调用activity的attach方法:

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*/);
    
}

这里第一次遇到了mFragments,它不是什么Fragment虽然名字很像,从代码很直观的看出1、一个运行时常量;2、从它的命名就可以看出这和Fragment有一定的关系了。在createController方法中又传入了一个HostCallbacks对象继承自FragmentHostCallback,来看一下这个FragmentController 类: image.png

image.png 从这些代码可以看出FragmentController更像是一个工具类,它只不过封装了些方法,最终的实现还是通过mHost中的mFragmentManager去实现,而这个mFragmentManager就是我们熟知的FragmentManager对象。

image.png

现在再回过头来看activity中的mFragments.attachHost(null)方法最终会来到FragmentManager的 attachController方法中

image.png image.png 这里的 mHost和mContainer就是activity内部类 HostCallback , mParent 指的是要依附的Fragment, 当前的过程是 activity 驱动的, 所以不存在fragment该值为 null

这里我们回顾一下整个流程,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;
        //通过遍历FragmentStore-->mActive,会先把最新的状态设置给所有的fragmentStateManager
        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

这段代码太简单了,就是上文提到过的直接通过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);
    //这里会把最新创建的fragmentStateManager保存到fragmentStore的mActive中
    mFragmentStore.makeActive(fragmentStateManager);
    //step2
    executeOps(records, isRecordPop, startIndex, endIndex);
    //step3
    fragmentStateManager.moveToExpectedState();
    //step4
    moveToState(mCurState, true);
       
}

来看一下executeOpsTogether中的操作

step1:创建fragmentStateManager并和fragment相关联,在创建的时候也会把fragmentManager最新的生命周期状态设置给它,这样看起来其实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方法中,在之前已经通过遍历fragmentStore的mActive,把最新的生命周期状态设置给fragmentStateManager了

//这些方法很明显就和平时所设计到的fragment生命周期回调事件相关了
//通过while循环会把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);
}

本文还有很多细节没展示出来,还是需要结合源码去看。

可以看出来,activity自己的生命周期执行的时候会通过mFragments.dispatch...到mHost.fragmentManager.dispatch...去调控fragment的生命周期状态;而fragment自身也能调整自己的生命周期状态,比如add一个事务的时候,经过上文提到的一系列操作,和activity调控一样最终都会来到fragmentStateManager的moveToExpectedState方法,在这个方法中去调整fragment的生命周期状态,而调整的依据也都是根据当前fragmentManager的生命周期状态即mCurState字段。