从FragmentActivity开始分析:
在FragmentActivity中有一个FragmentController对象mFragments,该对象的创建和初始化如下:
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
1.HostCallbacks的初始化
new HostCallbacks()的操作其实很简单,HostCallbacks是FragmentActivity的内部类,是继承自FragmentHostCallback的,而new HostCallbacks最终是调用到了FragmentHostCallback的构造器。FragmentHostCallback的构造器其实就是保存了相应的上下文对象,创建了Handler,该Handler是用来进行异步提交处理Runnable任务的。
FragmentHostCallback(@Nullable Activity activity, @NonNull Context context,
@NonNull Handler handler, int windowAnimations) {
mActivity = activity;
mContext = Preconditions.checkNotNull(context, "context == null");
mHandler = Preconditions.checkNotNull(handler, "handler == null");
// mWindowAnimations其实是等于0
mWindowAnimations = windowAnimations;
}
在创建HostCallbacks对象的时候,其父类FragmentHostCallback又会创建一个FragmentManager对象mFragmentManager,其实现类是FragmentManagerImpl。
2.FragmentController#createController
FragmentController的对象创建其实很简单,其构造器是私有的,所有通过静态方法创建。
public static FragmentController createController(@NonNull FragmentHostCallback> callbacks) {
return new FragmentController(checkNotNull(callbacks, "callbacks == null"));
}
3.FragmentActivity#onCreate
FragmentActivity作为Activity的生命周期开始位置,则也会通过mFragments这个FragmentController对象进行生命周期的分发,然后执行Fragment的生命周期
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragments.attachHost(null /*parent*/);
// 这里是状态恢复的情况下才会执行
if (savedInstanceState != null) {
// 从内存中取出状态保存是保存的数据
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreSaveState(p);
// Check if there are any pending onActivityResult calls to descendent Fragments.
if (savedInstanceState.containsKey(NEXT_CANDIDATE_REQUEST_INDEX_TAG)) {
mNextCandidateRequestIndex =
savedInstanceState.getInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG);
int[] requestCodes = savedInstanceState.getIntArray(ALLOCATED_REQUEST_INDICIES_TAG);
String[] fragmentWhos = savedInstanceState.getStringArray(REQUEST_FRAGMENT_WHO_TAG);
if (requestCodes == null || fragmentWhos == null ||
requestCodes.length != fragmentWhos.length) {
Log.w(TAG, "Invalid requestCode mapping in savedInstanceState.");
} else {
mPendingFragmentActivityResults = new SparseArrayCompat<>(requestCodes.length);
for (int i = 0; i < requestCodes.length; i++) {
mPendingFragmentActivityResults.put(requestCodes[i], fragmentWhos[i]);
}
}
}
}
if (mPendingFragmentActivityResults == null) {
mPendingFragmentActivityResults = new SparseArrayCompat<>();
mNextCandidateRequestIndex = 0;
}
super.onCreate(savedInstanceState);
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
// 向FragmentController分发生命周期事件
mFragments.dispatchCreate();
}
4.FragmentController#attachHost
public void attachHost(@Nullable Fragment parent) {
// 这里的mHost是FragmentHostCallback的子类对象,mFragmentManager
// 是FragmentManager对象,其实现类是FragmentManagerImpl
// 这里会初始化FragmentManager中的mContainer容器对象,该勇气是在Fragment创建
// ContentView的时候使用的,因为该
mHost.mFragmentManager.attachController(
mHost, mHost /*container*/, parent);
}
5.FragmentManager#attachController
这里其实就是做一定的数据绑定,把对应的Fragment、还有HostCallbacks等于FragmentManager做绑定,不过这里的mParent是为null的。因为在FragmentActivity传入的时候就是传的null
void attachController(@NonNull FragmentHostCallback> host,
@NonNull FragmentContainer container, @Nullable final Fragment parent) {
if (mHost != null) throw new IllegalStateException("Already attached");
mHost = host;
mContainer = container;
mParent = parent;
if (mParent != null) {
// 这里取决于是否依赖有导航的Fragment
updateOnBackPressedCallbackEnabled();
}
// 设置点击backPressed的回调
if (host instanceof OnBackPressedDispatcherOwner) {
OnBackPressedDispatcherOwner dispatcherOwner = ((OnBackPressedDispatcherOwner) host);
mOnBackPressedDispatcher = dispatcherOwner.getOnBackPressedDispatcher();
LifecycleOwner owner = parent != null ? parent : dispatcherOwner;
mOnBackPressedDispatcher.addCallback(owner, mOnBackPressedCallback);
}
// 获取对应的FragmentManager的视图模型
if (parent != null) {
mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
} else if (host instanceof ViewModelStoreOwner) {
ViewModelStore viewModelStore = ((ViewModelStoreOwner) host).getViewModelStore();
mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);
} else {
mNonConfig = new FragmentManagerViewModel(false);
}
}
6.FragmentController#dispatchCreate
FragmentController中的很多操作,其实都是通过HostCallbacks中的mFragmentManager对象,调用到FragmentManager或者FragmentManagerImpl中对应的方法。
public void dispatchCreate() {
// 调用FragmentManager#dispatchCreate方法
mHost.mFragmentManager.dispatchCreate();
}
7.FragmentManager#dispatchCreate
其实FragmentManager中有许多分发生命周期的方法,比如dispatchActivityCreated,就是在FragmentActivity中的onStart中调用,在dispatchStart之前,这些dispatch方法分发生命周期,其实最终都是调用到了一个方法:dispatchStateChange。只不过传入的参数不同,用来代表不同的生命周期时期。
void dispatchCreate() {
// mStateSaved是表示状态保存的标志。只有在保存状态的时候才会设置为true
mStateSaved = false;
mStopped = false;
// 在onCreate中调用的,就是传入Fragment.CREATED
// 如果实在onStart中调用的,则会传入的是Fragment.ACTIVITY_CREATED和
// Fragment.STARTED
dispatchStateChange(Fragment.CREATED);
}
在Fragment中,最新的AndroidX的版本,只有六个状态:
static final int INITIALIZING = -1; // Not yet attached.
static final int ATTACHED = 0; // Attached to the host.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // Fully created, not started.
static final int STARTED = 3; // Created and started, not resumed.
static final int RESUMED = 4; // Created started and resumed.
8.FragmentManager#dispatchStateChange
这里其实主要就是调用了moveToState方法,在FragmentActivity调用FragmentController的对应的dispatch分发生命周期给Fragment的时候,最终都是调用了dispatchStateChange,而dispatchStateChange最终又是调用到了moveToState
private void dispatchStateChange(int nextState) {
try {
mExecutingActions = true;
// 向状态管理器中设置Fragment的下一个状态
// FragmentStore中会存储当前FragmentActivity中的Fragment
// 这里的moveToState移动Fragment的状态,会针对当前FragmentActivity中
// 的所有的Fragment来进行
mFragmentStore.dispatchStateChange(nextState);
moveToState(nextState, false);
} finally {
mExecutingActions = false;
}
// 这是执行事务提交的操作的。
// 在分发生命周期的时候,有可能有需要提交的事务
execPendingActions(true);
}
9.FragmentStore#dispatchStateChange
void dispatchStateChange(int state) {
// 取出该Fragment的状态管理器,保存该Fragment的当前状态
for (Fragment f : mAdded) {
// 这里的mWho其实是Fragment对应的唯一标识
FragmentStateManager fragmentStateManager = mActive.get(f.mWho);
if (fragmentStateManager != null) {
fragmentStateManager.setFragmentManagerState(state);
}
}
// 遍历当前所有活跃的Fragment,设置状态
for (FragmentStateManager fragmentStateManager : mActive.values()) {
if (fragmentStateManager != null) {
fragmentStateManager.setFragmentManagerState(state);
}
}
}
10.FragmentManager#moveToState
将Fragment的状态修改为newState,如果FragmentManager修改状态或者always为true的话,则其他任何的Fragment也会改变状态
void moveToState(int newState, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
// 如果always=false,并且当前状态与新的状态一致,则不进行任何修改
if (!always && newState == mCurState) {
return;
}
mCurState = newState;
// 从Fragment存储中取出所有已经添加的Fragment,进行遍历
for (Fragment f : mFragmentStore.getFragments()) {
moveFragmentToExpectedState(f);
}
// 取出所有活跃的Fragment,包括已经删除和分离的Fragment
for (Fragment f : mFragmentStore.getActiveFragments()) {
if (f != null && !f.mIsNewlyAdded) {
moveFragmentToExpectedState(f);
}
}
// 对延迟启动的Fragment进行状态修改
// 这里是遍历FragmentStore中的mActive,取出活跃Fragment
// 判断Fragment的mDeferStart是否为true
startPendingDeferredFragments();
if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
mHost.onSupportInvalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
}
11.FragmentManager#moveFragmentToExpectedState
将Fragment移动到最新的状态或者是FragmentStore中FragmentStateManager中的状态,具体要取决于FragmentStore中的状态是否正确触发。
本方法是由moveToState(int newState, boolean always)遍历触发,可能会调用多次,如果存在多个fragment的话。
void moveFragmentToExpectedState(@NonNull Fragment f) {
if (!mFragmentStore.containsActiveFragment(f.mWho)) {
if (isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "Ignoring moving " + f + " to state " + mCurState
+ "since it is not added to " + this);
}
return;
}
// 将Fragment状态移动到当前最新的状态
// 这里最终调用到
moveToState(f);
if (f.mView != null) {
// Move the view if it is out of order
Fragment underFragment = mFragmentStore.findFragmentUnder(f);
if (underFragment != null) {
final View underView = underFragment.mView;
// make sure this fragment is in the right order.
final ViewGroup container = f.mContainer;
int underIndex = container.indexOfChild(underView);
int viewIndex = container.indexOfChild(f.mView);
if (viewIndex < underIndex) {
container.removeViewAt(viewIndex);
container.addView(f.mView, underIndex);
}
}
if (f.mIsNewlyAdded && f.mContainer != null) {
// Make it visible and run the animations
if (f.mPostponedAlpha > 0f) {
f.mView.setAlpha(f.mPostponedAlpha);
}
f.mPostponedAlpha = 0f;
f.mIsNewlyAdded = false;
// run animations:
FragmentAnim.AnimationOrAnimator anim = FragmentAnim.loadAnimation(
mHost.getContext(), mContainer, f, true);
if (anim != null) {
if (anim.animation != null) {
f.mView.startAnimation(anim.animation);
} else {
anim.animator.setTarget(f.mView);
anim.animator.start();
}
}
}
}
// 完成对Fragment的show或者hide操作
if (f.mHiddenChanged) {
completeShowHideFragment(f);
}
}
12.FragmentManager#moveToState(Fragment f, int newState)
本方法与上面的moveToState并不相同,是上面方法的重载。不要混淆。
在这里改变Fragment状态的同时,会执行Fragment对应的生命周期方法,比如onCreate、onStart、onResume、onPause等方法。
void moveToState(@NonNull Fragment f, int newState) {
// 设置该Fragment的状态管理器
FragmentStateManager fragmentStateManager = mFragmentStore.getFragmentStateManager(f.mWho);
if (fragmentStateManager == null) {
// Ideally, we only call moveToState() on active Fragments. However,
// in restoreSaveState() we can call moveToState() on retained Fragments
// just to clean them up without them ever being added to mActive.
// For these cases, a brand new FragmentStateManager is enough.
fragmentStateManager = new FragmentStateManager(mLifecycleCallbacksDispatcher, f);
// Only allow this FragmentStateManager to go up to CREATED at the most
fragmentStateManager.setFragmentManagerState(Fragment.CREATED);
}
// 对比传入的newState和Fragment状态管理器中的状态哪个更小,取出更小的状态
newState = Math.min(newState, fragmentStateManager.computeMaxState());
// 如果当前Fragment的状态小于新的状态
// Fragment中的状态有6个,当当前Fragment的状态小于新的状态的时候
// 则需要向下依次增大当前Fragment的状态,将当前Fragment的状态设置为
// 当前状态的下一个状态
if (f.mState <= newState) {
// If we are moving to the same state, we do not need to give up on the animation.
if (f.mState < newState && !mExitAnimationCancellationSignals.isEmpty()) {
// The fragment is currently being animated... but! Now we
// want to move our state back up. Give up on waiting for the
// animation and proceed from where we are.
cancelExitAnimation(f);
}
switch (f.mState) {
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
if (isLoggingEnabled(Log.DEBUG)) Log.d(TAG, "moveto ATTACHED: " + f);
// 如果当前Fragment有目标Fragment,则至少需要将目标Fragment
// 的生命周期设置为CREATED状态
if (f.mTarget != null) {
if (!f.mTarget.equals(findActiveFragment(f.mTarget.mWho))) {
throw new IllegalStateException("Fragment " + f
+ " declared target fragment " + f.mTarget
+ " that does not belong to this FragmentManager!");
}
if (f.mTarget.mState < Fragment.CREATED) {
moveToState(f.mTarget, Fragment.CREATED);
}
f.mTargetWho = f.mTarget.mWho;
f.mTarget = null;
}
if (f.mTargetWho != null) {
Fragment target = findActiveFragment(f.mTargetWho);
if (target == null) {
throw new IllegalStateException("Fragment " + f
+ " declared target fragment " + f.mTargetWho
+ " that does not belong to this FragmentManager!");
}
if (target.mState < Fragment.CREATED) {
moveToState(target, Fragment.CREATED);
}
}
// 如果当前状态是初始化状态,而新的状态比初始化状态大
// 则需要将当前状态设置为下一个状态,即ATTACHED状态
fragmentStateManager.attach(mHost, this, mParent);
}
// fall through
case Fragment.ATTACHED:
// 如果当前状态是ATTACHED状态,新的状态比当前状态大
// 则需要将当前Fragment的状态设置为下一个状态CREATED
if (newState > Fragment.ATTACHED) {
fragmentStateManager.create();
}
// fall through
case Fragment.CREATED:
// We want to unconditionally run this anytime we do a moveToState that
// moves the Fragment above INITIALIZING, including cases such as when
// we move from CREATED => CREATED as part of the case fall through above.
if (newState > Fragment.INITIALIZING) {
fragmentStateManager.ensureInflatedView();
}
if (newState > Fragment.CREATED) {
// 创建Fragment对应的View
// mContainer其实就是HostCallbacks,在FragmentActivity
// 的onCreate方法中调用FragmentController.attachHost
// 方法的时候,会将HostCallbacks对象传给FragmentController
fragmentStateManager.createView(mContainer);
fragmentStateManager.activityCreated();
fragmentStateManager.restoreViewState();
}
// fall through
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
fragmentStateManager.start();
}
// fall through
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
fragmentStateManager.resume();
}
}
} else if (f.mState > newState) {
// 如果当前Fragment的状态大于新的状态
// 说明当前Fragment已经要开始执行onPause、onStop等生命周期
// 所以当前Fragment的状态就需要逆序依次减小
// 比如在onPause的时候,状态就从RESUMED变成STARTED
// 在onStop的时候,状态就从STARTED变成ACTIVITY_CREATED
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
fragmentStateManager.pause();
}
// fall through
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
fragmentStateManager.stop();
}
// fall through
case Fragment.ACTIVITY_CREATED:
// Fragment要回调onDestroyViews的时候
// 其实是处于ACTIVITY_CREATED这个状态
if (newState < Fragment.ACTIVITY_CREATED) {
if (isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "movefrom ACTIVITY_CREATED: " + f);
}
if (f.mView != null) {
// Need to save the current view state if not
// done already.
if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
fragmentStateManager.saveViewState();
}
}
FragmentAnim.AnimationOrAnimator anim = null;
if (f.mView != null && f.mContainer != null) {
// Stop any current animations:
f.mContainer.endViewTransition(f.mView);
f.mView.clearAnimation();
// If parent is being removed, no need to handle child animations.
if (!f.isRemovingParent()) {
if (mCurState > Fragment.INITIALIZING && !mDestroyed
&& f.mView.getVisibility() == View.VISIBLE
&& f.mPostponedAlpha >= 0) {
anim = FragmentAnim.loadAnimation(mHost.getContext(),
mContainer, f, false);
}
f.mPostponedAlpha = 0;
// Robolectric tests do not post the animation like a real device
// so we should keep up with the container and view in case the
// fragment view is destroyed before we can remove it.
ViewGroup container = f.mContainer;
View view = f.mView;
if (anim != null) {
f.setStateAfterAnimating(newState);
FragmentAnim.animateRemoveFragment(f, anim,
mFragmentTransitionCallback);
}
container.removeView(view);
// If the local container is different from the fragment
// container, that means onAnimationEnd was called, onDestroyView
// was dispatched and the fragment was already moved to state, so
// we should early return here instead of attempting to move to
// state again.
if (container != f.mContainer) {
return;
}
}
}
// If a fragment has an exit animation (or transition), do not destroy
// its view immediately and set the state after animating
if (mExitAnimationCancellationSignals.get(f) == null) {
destroyFragmentView(f);
} else {
f.setStateAfterAnimating(newState);
}
}
// fall through
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
boolean beingRemoved = f.mRemoving && !f.isInBackStack();
if (beingRemoved || mNonConfig.shouldDestroy(f)) {
makeInactive(fragmentStateManager);
} else {
if (f.mTargetWho != null) {
Fragment target = findActiveFragment(f.mTargetWho);
if (target != null && target.getRetainInstance()) {
// Only keep references to other retained Fragments
// to avoid developers accessing Fragments that
// are never coming back
f.mTarget = target;
}
}
}
if (mExitAnimationCancellationSignals.get(f) != null) {
// We are waiting for the fragment's view to finish
// animating away. Just make a note of the state
// the fragment now should move to once the animation
// is done.
// Shared elements require that we wait on multiple Fragments, so if
// any of them are animating we will continue to wait.
f.setStateAfterAnimating(newState);
newState = Fragment.CREATED;
} else {
fragmentStateManager.destroy(mHost, mNonConfig);
}
}
// fall through
case Fragment.ATTACHED:
if (newState < Fragment.ATTACHED) {
fragmentStateManager.detach(mNonConfig);
}
}
}
if (f.mState != newState) {
if (isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "moveToState: Fragment state for " + f + " not updated inline; "
+ "expected state " + newState + " found " + f.mState);
}
f.mState = newState;
}
}
13.FragmentManager#execPendingActions
在针对Fragment的状态修改执行完成之后,继续分析第八步中调用的execPendingActions方法。
execPendingActions方法只能是在主线程中执行,如果是在异步线程中,则会抛出异常。"Must be called from main thread of fragment host"
本方法其实就是执行对应的事务,scheduleCommit方法中会执行Runnable对象mExecCommit,在mExecCommit的run方法中调用了execPendingActions方法,进行具体事务的提交。scheduleCommit是在enqueueAction调用,而enqueueAction是在事务对象BackStackRecord中的commit方法由commitInternal调用的。
boolean execPendingActions(boolean allowStateLoss) {
// 确保执行是处于就绪阶段,即没有正在执行的事务,也HostCallbacks也不为null
// 且是在主线程中
ensureExecReady(allowStateLoss);
boolean didSomething = false;
// 这里的操作,其实就是在mPendingActions中取出BackStackRecord
// mPendingActions中存的是OpGenerator,而BackStackRecord实现了该接口
// mTmpRecords存的就是BackStackRecord
// 所以这里的目的就算将待执行的事务添加到mTmpRecords
// 而在mTmpIsPop对应位置会根据是否允许添加到回退栈而设置true还是false
// 这里如果mPendingActions为null,则直接返回false
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
// 这里是删除冗余操作,并且执行事务
// 所谓的冗余操作:比如一次事务提交,对一个Fragment进行了add
// 又进行了remove,然后又进行了add,这样只有最后一次add有效
// 在这里会修改事务的状态,比如将replace的事务变成ADD的
// 最终就会执行处理事务
// 如果没有回退栈相关,则是调用事务BackStackRecord.executeOps方法
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
didSomething = true;
}
updateOnBackPressedCallbackEnabled();
// 执行延迟启动的Fragment,修改其状态
doPendingDeferredStart();
// 这里为了防止列表错误,将mActive的值置为null
// 而不是在Fragment变为非活动状态的时候将其删除。
// 但是在执行事务结束时会清理列表
mFragmentStore.burpActive();
return didSomething;
}
14.FragmentManager#removeRedundantOperationsAndExecute
这里的主要目的就是为了移除事务提交过程中,事务列表中冗余的BackStackRecord对象。
private void removeRedundantOperationsAndExecute(@NonNull ArrayList records,
@NonNull ArrayList isRecordPop) {
if (records.isEmpty()) {
return;
}
if (records.size() != isRecordPop.size()) {
throw new IllegalStateException("Internal error with the back stack records");
}
// 针对与计划处理的事务有交互的任何延迟的事务,进行强制执行
// 不过这些事务是过去延迟处理,但是当前已经准备好的事务
executePostponedTransaction(records, isRecordPop);
final int numRecords = records.size();
int startIndex = 0;
for (int recordNum = 0; recordNum < numRecords; recordNum++) {
final boolean canReorder = records.get(recordNum).mReorderingAllowed;
if (!canReorder) {
// 执行先前的所有事务
if (startIndex != recordNum) {
executeOpsTogether(records, isRecordPop, startIndex, recordNum);
}
// 执行所有不允许重新排序的出栈操作或者事务的添加操作
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);
}
}
15.FragmentManager#executeOpsTogether
private void executeOpsTogether(@NonNull ArrayList records,
@NonNull ArrayList isRecordPop, int startIndex, int endIndex) {
final boolean allowReordering = records.get(startIndex).mReorderingAllowed;
boolean addToBackStack = false;
if (mTmpAddedFragments == null) {
mTmpAddedFragments = new ArrayList<>();
} else {
mTmpAddedFragments.clear();
}
mTmpAddedFragments.addAll(mFragmentStore.getFragments());
Fragment oldPrimaryNav = getPrimaryNavigationFragment();
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
final BackStackRecord record = records.get(recordNum);
final boolean isPop = isRecordPop.get(recordNum);
if (!isPop) {
// 如果是不允许出栈的,修改事务的操作状态
// 比如将replace的操作也变成了ADD操作
oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
} else {
oldPrimaryNav = record.trackAddedFragmentsInPop(mTmpAddedFragments, oldPrimaryNav);
}
addToBackStack = addToBackStack || record.mAddToBackStack;
}
mTmpAddedFragments.clear();
if (!allowReordering) {
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex,
false, mFragmentTransitionCallback);
}
// 这里是具体执行对Fragment的add、replace、hide、show等操作的
executeOps(records, isRecordPop, startIndex, endIndex);
int postponeIndex = endIndex;
if (allowReordering) {
ArraySet addedFragments = new ArraySet<>();
addAddedFragments(addedFragments);
postponeIndex = postponePostponableTransactions(records, isRecordPop,
startIndex, endIndex, addedFragments);
makeRemovedFragmentsInvisible(addedFragments);
}
if (postponeIndex != startIndex && allowReordering) {
// need to run something now
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
postponeIndex, true, mFragmentTransitionCallback);
moveToState(mCurState, true);
}
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
final BackStackRecord record = records.get(recordNum);
final boolean isPop = isRecordPop.get(recordNum);
if (isPop && record.mIndex >= 0) {
record.mIndex = -1;
}
record.runOnCommitRunnables();
}
if (addToBackStack) {
reportBackStackChanged();
}
}