系列
Fragment (一):Fragment使用详解
Fragment (二):Activity 和Fragment 的异常销毁、状态保存和恢复机制
Fragment (三):源码解析Fragment 返回栈原理
返回栈涉及的类
在看本文前需要熟悉Fragment 的使用,不清楚的可先看:Fragment使用详解
本文源码都是都是v25 的support v4 包下的源码。
基本操作:getFragmentManager().beginTransaction().add(R.id.container, fragment).addToBackStack(null).commit();
getFragmentManager():实际返回值是FragmentManagerImpl 对象。
beginTransaction():实际返回值是BackStackRecord 对象。
BackStackRecord.Op
代表Fragment 事务中的一次操作,如add、remove等。BackStackRecord
一个BackStackRecord 代表一次Fragment 事务。
BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator 实现了OpGenerator
Field:
1、ArrayList<BackStackRecord.Op> mOps:保存一次Fragment 事务的所有Op 操作。
2、FragmentManagerImpl mManager:保存getFragmentManager() 的返回值。FragmentManagerImpl.OpGenerator
相当于BackStackRecord。一个OpGenerator 对象能产生相应的一个BackStackRecord 对象,该BackStackRecord 对象可能是OpGenerator 对象本身也可能来自返回栈。FragmentManagerImpl
Field:
1、ArrayList<FragmentManagerImpl.OpGenerator> mPendingActions:存放当前尚未执行的所有事务,用于产生mTmpRecords 和mTmpIsPop。
2、ArrayList<BackStackRecord> mTmpRecords:存放当前尚未执行的所有事务,由mPendingActions 转化而来。
3、ArrayList<Boolean> mTmpIsPop:mTmpRecords 中对应下标下的事务是否是出栈。
4、ArrayList<BackStackRecord> mBackStack:返回栈,存放mTmpRecords 中进栈的事务。
5、ArrayList<Fragment> mAdded:存放前台Fragment,即已调用了add() 但尚未进入返回栈或被被销毁的Fragment。
6、ArrayList<Fragment> mActive:存放前台Fragment 和返回栈中的Fragment。
7、ArrayList<Fragment> mTmpAddedFragments:临时的mAdded 。
看源码前先了解下:
1、Fragment 的各种状态:
static final int INITIALIZING = 0; // Not yet created.销毁。
static final int CREATED = 1; // Created.没有视图但fragment已创建,比如:fragment处于返回栈中。
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.宿主Activity已创建完毕,就是fragment生命周期已调用到onActivityCreated(),已创建视图。
static final int STOPPED = 3; // Fully created, not started.不显示
static final int STARTED = 4; // Created and started, not resumed.不聚焦
static final int RESUMED = 5; // Created started and resumed.聚焦
事务提交
流程
- BackStackRecord:addToBackStack() //若调用则标志事务进栈,否则不进栈。
- BackStackRecord:commit()
- BackStackRecord:commitInternal()
- FragmentManagerImpl:enqueueAction() //BackStackRecord加入mPendingActions。
- FragmentManagerImpl:generateOpsForPendingActions() //mPendingActions转换为mTmpRecords 和mTmpIsPop。
- FragmentManagerImpl:executeOpsTogether() //遍历mTmpRecords。1、将Op是replace 的替换为多个remove 和一个add。2、执行所有Op,更新mAdded 和mActive。每个事务的最后一个Op时,对mAdded 和mActive 中所有Fragment 切换生命周期到预期的状态,同时,在此过程中对每一个从前台退回到返回栈的Fragment调用它的顶级View 的saveHierarchyState() 保存View状态,对每一个从返回栈出栈变为前台的Fragment调用它的顶级View的restoreHierarchyState() 恢复View状态。
源码
BackStackRecord:
public FragmentTransaction addToBackStack(String name) {
if (!mAllowAddToBackStack) {
throw new IllegalStateException(
"This FragmentTransaction is not allowed to be added to the back stack.");
}
mAddToBackStack = true;//
mName = name;
return this;
}
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(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);//该BackStackRecord对象加入mPendingActions
return mIndex;
}
FragmentManagerImpl:
/**
* Adds an action to the queue of pending actions.
*/
public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mDestroyed || mHost == null) {
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList<>();
}
mPendingActions.add(action);//
scheduleCommit();//用UI线程的Handler发送Runnable
}
}
private 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);//发送runnable
}
}
}
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
/**
* Only call from main thread!
*/
public boolean execPendingActions() {
ensureExecReady(true);
boolean didSomething = false;
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
//mPendingActions 转换为mTmpRecords 和mTmpIsPop。
mExecutingActions = true;
try {
optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);//优化并处理所有Op
} finally {
cleanupExec();
}
didSomething = true;
}
doPendingDeferredStart();
return didSomething;
}
/**
* Adds all records in the pending actions to records and whether they are add or pop
* operations to isPop. After executing, the pending actions will be empty.
*/
private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isPop) {
int numActions;
synchronized (this) {
if (mPendingActions == null || mPendingActions.size() == 0) {
return false;
}
numActions = mPendingActions.size();
for (int i = 0; i < numActions; i++) {
mPendingActions.get(i).generateOps(records, isPop);
//若该事务是出栈,则从mBackStack 中取出一个事务即BackStackRecord加入mTmpRecords;
//否则,将当前action 加入mTmpRecords,若该事务进栈还要添加到mBackStack中。
}
mPendingActions.clear();//清空
mHost.getHandler().removeCallbacks(mExecCommit);
}
return numActions > 0;
}
private void optimizeAndExecuteOps(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isRecordPop) {
......
// Force start of any postponed transactions that interact with scheduled transactions:
executePostponedTransaction(records, isRecordPop);