Android-Fragment事务管理原理分析
一、Fragment事务提交的部分操作
1.相关源码概念
FragmetActivity的getSupportFragmentManager()内部是通过FragmentController.getSupportFragmentManager,而FragmentController的内部是获取的HostCallbacks对象中的FragmentManager对象,这个对象在最新版本的Androidx源码中,虽然是FragmentManagerImpl对象,但是FragmentManagerImpl其实是一个空子类。
通过FragmentManager.beginTransaction()获取FragmentTransaction对象,而FragmentManager.beginTransaction()中的方法实现如下:
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
FragmentTransaction.add
FragmentTransaction.remove
FragmentTransaction.replace
FragmentTransaction.hide
FragmentTransaction.show
FragmentTransaction.setPrimaryNavigationFragment
FragmentTransaction.addToBackStack
FragmentTransaction.commit
FragmentTransaction的实现类只有一个BackStackRecord
其实这些所有的add、replace等,最终都是将Fragment的状态变成了ADD,然后最终在执行的时候,都是通过调用FragmentManager.moveToState方法,createView,一直开始执行生命周期,而在FragmentManager.moveToState方法中,每个生命周期执行完成之后,都会继续调用moveToState转成下一个步骤的生命周期状态。
使用事务,是为了保证连续的操作是原子性的。
调用hide和show的时候,其实并不会去走生命周期。
2.FragmentActivity#getSupportFragmentManager()
该源码逻辑在在上面已经说了,这里就贴下源码:
// FragmentActivity.java
public FragmentManager getSupportFragmentManager() {
// 这里的mFragments其实就是FragmentController对象
return mFragments.getSupportFragmentManager();
}
// FragmentController.java
public FragmentManager getSupportFragmentManager() {
// 获取HostCallbacks对象中创建的FragmentManager对象
return mHost.mFragmentManager;
}
// FragmentHostCallback.java 这是HostCallbacks的父类,泛型是传入的FragmentActivity
final FragmentManager mFragmentManager = new FragmentManagerImpl();
3.FragmentManager#beginTransaction
// 获取事务类,BackStackRecord其实就是FragmentTransaction的子类实现
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
// 从BackStackRecord的源码可以看出,BackStackRecord实现了FragmentTransaction抽象类
// 还实现了FragmentManager.OpGenerator接口,所以在这个流程中,保存事务的时候,可能会以FragmentManager.OpGenerator对象
// 也可能会以BackStackRecord保存,这是同一个。
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManager.OpGenerator {
4.FragmentTransaction#add
(1)直接传入Fragment的Class对象,在内部创建Fragment
public final FragmentTransaction add(@NonNull Class<? extends Fragment> fragmentClass,
@Nullable Bundle args, @Nullable String tag) {
return add(createFragment(fragmentClass, args), tag);
}
public FragmentTransaction add(@NonNull Fragment fragment, @Nullable String tag) {
// 调用add方法,设置Op的mCmd指令为OP_ADD
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
(2)传入布局控件id和Fragment对象
public final FragmentTransaction add(@IdRes int containerViewId,
@NonNull Class<? extends Fragment> fragmentClass, @Nullable Bundle args) {
return add(containerViewId, createFragment(fragmentClass, args));
}
public FragmentTransaction add(@IdRes int containerViewId, @NonNull Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}
5.FragmentTransaction#doAddOp
如果传入的是Fragment的Class对象,这doAddOp操作的第一个参数直接传0,如果是传入具体的containerViewId,则使用具体的containerViewId
// 这步的主要操作就是设置tag和containerId
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;
}
// 判断布局id是否为0,如果不为0,设置给fragment对象的mContainerId值
// 这是用于在fragment对象进行createView的时候使用
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);
}
// 设置宿主ID为布局ID
fragment.mContainerId = fragment.mFragmentId = containerViewId;
}
// 将fragment和opcmd指令封装成一个Op对象,Op对象其是对于Fragment的操作对象,封装fragment的相关操作信息
addOp(new Op(opcmd, fragment));
}
6.FragmentTransaction#addOp
void addOp(Op op) {
// 将每个Fragment相关的操作对象添加到ArrayList集合中,用于提交的时候使用
mOps.add(op);
op.mEnterAnim = mEnterAnim;
op.mExitAnim = mExitAnim;
op.mPopEnterAnim = mPopEnterAnim;
op.mPopExitAnim = mPopExitAnim;
}
7.BackStackRecord#commit
BackStackRecord的提交有四个方法,这里做统一分析:然后最后就分析commit()的后续流程,因为大体相同,主要就是异步和同步提交不同。
// commit() 在主线程中异步执行,其实也是 Handler 抛出任务,等待主线程调度执行。
// commit需要在Activity保存状态之前提交,否则会报错。
// 因为Activity出现异常需要恢复状态,在保存状态之后的commit会丢失
@Override
public int commit() {
return commitInternal(false);
}
// commitAllowingStateLoss() 也是异步执行,但它的不同之处在于,允许在 Activity
// 保存状态之后调用,也就是说它遇到状态丢失不会报错。
@Override
public int commitAllowingStateLoss() {
return commitInternal(true);
}
// 这是同步执行的。立即提交事务。与FragmentManager.executePendingTransactions
// 类似,但是推荐使用commitNow。因为executePendingTransactions会一次性
// 执行所有待执行的事务,可能会有副作用。而且executePendingTransactions方法提交
// 的事务可能不会被添加到FragmentManager的回退栈中,因为这样直接提交可能会影响
// 其他异步执行任务在栈中的顺序
// commitNow的提交也不能在状态保存之后进行
// TODO:这两个方法在调用的时候,是禁止使用回退栈功能的
@Override
public void commitNow() {
disallowAddToBackStack();
mManager.execSingleAction(this, false);
}
@Override
public void commitNowAllowingStateLoss() {
disallowAddToBackStack();
mManager.execSingleAction(this, true);
}
8.BackStackRecord#commitInternal
int commitInternal(boolean allowStateLoss) {
if (mCommitted) throw new IllegalStateException("commit already called");
if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
Log.v(TAG, "Commit: " + this);
LogWriter logw = new LogWriter(TAG);
PrintWriter pw = new PrintWriter(logw);
dump(" ", pw);
pw.close();
}
mCommitted = true;
// 这里的index,其实是记录当前事务可以放置的位置的
// 如果是fragment-1.1.0版本,是采用两个集合的方式,一个集合保存BackStackRecord
// 另一个集合保存因为回退之后,空出来的位置的索引
// 但是在fragment-1.2.1版本中,采用的是AtomicInteger,比较并交换的做法
if (mAddToBackStack) {
// 这里是回退栈可用的情况,则需要计算一个index
// 这里因为Androidx版本的区别,实现也不同。
// 这里的代码是fragment-1.2.1版本的库
mIndex = mManager.allocBackStackIndex();
// 如果是fragment-1.1.0的库,则与这里实现不同,如下所示
// mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
9.FragmentManager#allocBackStackIndex()
这是fragment-1.2.1-androidx的源码
这里采用AtomicInteger,是为了保证在异步提交事务处理的时候,保证index的一个原子性
int allocBackStackIndex() {
return mBackStackIndex.getAndIncrement();
}
对比fragment-1.1.0-androidx的源码
在这里,是采用两个ArrayList数组的方式,一个用来保存当前提交的事务,而另一个是用来保存当前事务集合中的可用位置,这样说可能比较抽象,看源码分析。
public int allocBackStackIndex(BackStackRecord bse) {
synchronized (this) {
// 第一次提交的时候,mAvailBackStackIndices是为null或者size==0的
// 所以执行if条件
if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) {
// 初始化mBackStackIndices保存事务
if (mBackStackIndices == null) {
mBackStackIndices = new ArrayList<BackStackRecord>();
}
// 找到当前添加的事务的索引位置,在这里,因为是添加到了mBackStackIndices的末尾
// 所以添加的集合的索引位置其实就是添加之前的集合的长度
int index = mBackStackIndices.size();
if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse);
mBackStackIndices.add(bse);
return index;
} else {
int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1);
if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse);
mBackStackIndices.set(index, bse);
return index;
}
}
}
// 向之前回退位置的存储集合位置上添加事务
public void setBackStackIndex(int index, BackStackRecord bse) {
synchronized (this) {
if (mBackStackIndices == null) {
mBackStackIndices = new ArrayList<BackStackRecord>();
}
int N = mBackStackIndices.size();
// 如果index小于mBackStackIndices的长度,说明mBackStackIndices中有取出添加到回退栈的事务
// 那么基于复用原则,继续复用之前取出的位置存放当前添加的事务
if (index < N) {
if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse);
mBackStackIndices.set(index, bse);
} else {
// 如果存储集合的长度是小于要添加的位置,则向集合的末尾添加事务
while (N < index) {
mBackStackIndices.add(null);
if (mAvailBackStackIndices == null) {
mAvailBackStackIndices = new ArrayList<Integer>();
}
if (DEBUG) Log.v(TAG, "Adding available back stack index " + N);
mAvailBackStackIndices.add(N);
N++;
}
if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse);
// 这里是index==N的条件
mBackStackIndices.add(bse);
}
}
}
// 释放存储事务集合中的事务
public void freeBackStackIndex(int index) {
synchronized (this) {
// 在释放mBackStackIndices中的事务的时候,并不是单纯的将集合的index位置释放,然后重新排序集合
// 而是采用一个null来填充,用于下一次的复用
mBackStackIndices.set(index, null);
if (mAvailBackStackIndices == null) {
mAvailBackStackIndices = new ArrayList<Integer>();
}
if (DEBUG) Log.v(TAG, "Freeing back stack index " + index);
// 这里存储的其实就是之前被释放的事务的位置,这样的做法,其实就是方便
// 下一次添加事务的时候,能够精准的找到mBackStackIndices中对应的位置存放事务
mAvailBackStackIndices.add(index);
}
}
10.FragmentManager#enqueueAction
void enqueueAction(@NonNull OpGenerator action, boolean allowStateLoss) {
// 判断是否需要检查状态,即是否允许在保存状态之后提交事务进行丢弃
// 如果allowStateLoss是false,则需要检查当前事务提交的时候是否已经进行onSaveInstanceState操作
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) {
// 如果HostCallbacks对象为null,判断allowStateLoss是否为true
// 如果为true,则直接return,否则抛出异常,提示activity已经被销毁
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();
}
}
11.FragmentManager#scheduleCommit
// 执行异步任务
void scheduleCommit() {
synchronized (mPendingActions) {
boolean postponeReady =
mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
boolean pendingReady = mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
// 这里就是采用之前添加到HostCallbacks对象中的Handler来执行异步任务操作
// 首先删除上一次执行的提交的任务
mHost.getHandler().removeCallbacks(mExecCommit);
// 然后再执行当前新的提交请求
// mExecCommit其实是一个Runnable对象
mHost.getHandler().post(mExecCommit);
updateOnBackPressedCallbackEnabled();
}
}
}
12.FragmentManager#mExecCommit对象
private Runnable mExecCommit = new Runnable() {
@Override
public void run() {
// 由HostCallbacks中的Handler进行执行该任务
execPendingActions(true);
}
};
13.FragmentManager#execPendingActions
// 只能从主线程调用该方法
boolean execPendingActions(boolean allowStateLoss) {
// 确保执行是处于就绪阶段,即没有正在执行的事务,也HostCallbacks也不为null
// 且是在主线程中,并且初始化mTmpRecords和mTmpIsPop
// 这里就是针对execPendingActions的方法执行的线程检查的操作
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<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");
}
// 针对与计划处理的事务有交互的任何延迟的事务,进行强制执行
// 不过这些事务是过去延迟处理,但是当前已经准备好的事务
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<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
final boolean allowReordering = records.get(startIndex).mReorderingAllowed;
boolean addToBackStack = false;
// 添加Fragment到集合中,该集合是ADD状态的Fragment集合
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操作,这里其实就是想ADD状态集合添加Fragment
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<Fragment> 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();
}
}
16.BackStackRecord#expandOps
这里主要是找到旧的Fragment的导航
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: {
// REPLACE状态,如果是已经添加的,则需要删除已经添加的,然后再一次添加新的
final Fragment f = op.mFragment;
final int containerId = f.mContainerId;
boolean alreadyAdded = false;
for (int i = added.size() - 1; i >= 0; i--) {
final Fragment old = added.get(i);
if (old.mContainerId == containerId) {
// 判断旧的Fragment和当前要添加的Fragment是否一致
if (old == f) {
alreadyAdded = true;
} else {
// 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));
opNum++;
oldPrimaryNav = null;
}
final Op removeOp = new Op(OP_REMOVE, old);
removeOp.mEnterAnim = op.mEnterAnim;
removeOp.mPopEnterAnim = op.mPopEnterAnim;
removeOp.mExitAnim = op.mExitAnim;
removeOp.mPopExitAnim = op.mPopExitAnim;
mOps.add(opNum, removeOp);
added.remove(old);
opNum++;
}
}
}
// 如果是已经添加,则先删除已经添加的,然后在加入新的
// 再将op.mCmd改成OP_ADD
if (alreadyAdded) {
mOps.remove(opNum);
opNum--;
} else {
op.mCmd = OP_ADD;
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));
opNum++;
// Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
oldPrimaryNav = op.mFragment;
}
break;
}
}
return oldPrimaryNav;
}
17.FragmentManager#executeOps
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) {
record.bumpBackStackNesting(-1);
// Only execute the add operations at the end of
// all transactions.
boolean moveToState = i == (endIndex - 1);
record.executePopOps(moveToState);
} else {
record.bumpBackStackNesting(1);
// 执行事务
record.executeOps();
}
}
}
18.BackStackRecord#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.setNextTransition(mTransition);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mEnterAnim);
mManager.setExitAnimationOrder(f, false);
mManager.addFragment(f);
break;
case OP_REMOVE:
f.setNextAnim(op.mExitAnim);
mManager.removeFragment(f);
break;
case OP_HIDE:
f.setNextAnim(op.mExitAnim);
mManager.hideFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.mEnterAnim);
mManager.setExitAnimationOrder(f, false);
mManager.showFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mExitAnim);
mManager.detachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mEnterAnim);
mManager.setExitAnimationOrder(f, false);
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);
}
if (!mReorderingAllowed && op.mCmd != OP_ADD && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed) {
// 事务提交之后,根据当前状态,执行fragment的生命周期
mManager.moveToState(mManager.mCurState, true);
}
}
19.FragmentManager#addFragment/removeFragment/hideFragment/showFragment/detachFragment/attachFragment
void addFragment(@NonNull Fragment fragment) {
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "add: " + fragment);
makeActive(fragment);
if (!fragment.mDetached) {
// 向mAdded集合中添加fragment,mAdded集合是保存添加的Fragment
// 用于在moveToState的处理添加的Fragment
mFragmentStore.addFragment(fragment);
fragment.mRemoving = false;
if (fragment.mView == null) {
// 添加之后,设置隐藏状态为false
fragment.mHiddenChanged = false;
}
if (isMenuAvailable(fragment)) {
mNeedMenuInvalidate = true;
}
}
}
void removeFragment(@NonNull Fragment fragment) {
if (isLoggingEnabled(Log.VERBOSE)) {
Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting);
}
final boolean inactive = !fragment.isInBackStack();
if (!fragment.mDetached || inactive) {
// 从mAdded集合中删除fragment
mFragmentStore.removeFragment(fragment);
if (isMenuAvailable(fragment)) {
mNeedMenuInvalidate = true;
}
fragment.mRemoving = true;
setVisibleRemovingFragment(fragment);
}
}
void hideFragment(@NonNull Fragment fragment) {
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "hide: " + fragment);
if (!fragment.mHidden) {
// 设置fragment的隐藏状态为true
fragment.mHidden = true;
// Toggle hidden changed so that if a fragment goes through show/hide/show
// it doesn't go through the animation.
fragment.mHiddenChanged = !fragment.mHiddenChanged;
setVisibleRemovingFragment(fragment);
}
}
void showFragment(@NonNull Fragment fragment) {
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "show: " + fragment);
if (fragment.mHidden) {
// 设置fragment的隐藏状态
fragment.mHidden = false;
// Toggle hidden changed so that if a fragment goes through show/hide/show
// it doesn't go through the animation.
fragment.mHiddenChanged = !fragment.mHiddenChanged;
}
}
void detachFragment(@NonNull Fragment fragment) {
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "detach: " + fragment);
if (!fragment.mDetached) {
fragment.mDetached = true;
if (fragment.mAdded) {
// We are not already in back stack, so need to remove the fragment.
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "remove from detach: " + fragment);
mFragmentStore.removeFragment(fragment);
if (isMenuAvailable(fragment)) {
mNeedMenuInvalidate = true;
}
setVisibleRemovingFragment(fragment);
}
}
}
void attachFragment(@NonNull Fragment fragment) {
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "attach: " + fragment);
if (fragment.mDetached) {
fragment.mDetached = false;
if (!fragment.mAdded) {
mFragmentStore.addFragment(fragment);
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "add from attach: " + fragment);
if (isMenuAvailable(fragment)) {
mNeedMenuInvalidate = true;
}
}
}
}
20.FragmentManager#moveToState
void moveToState(int newState, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
if (!always && newState == mCurState) {
return;
}
mCurState = newState;
// 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 (Fragment f : mFragmentStore.getActiveFragments()) {
if (f != null && !f.mIsNewlyAdded) {
moveFragmentToExpectedState(f);
}
}
startPendingDeferredFragments();
if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
mHost.onSupportInvalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
}
21.FragmentManager#moveFragmentToExpectedState
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;
}
// 在CREATED状态的时候会创建View,保存在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();
}
}
}
}
// 是否隐藏的状态,如果是true,这执行完成隐藏显示Fragment的操作
if (f.mHiddenChanged) {
completeShowHideFragment(f);
}
}