一、Framgnet源码解析
(1)getSupportFragmentManager()源码
- mHost.mFragmentManager获取的是FragmentMananger的实现类FragmentManagerImpl。
@NonNull
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
//FragmentController.java
@NonNull
public FragmentManager getSupportFragmentManager() {
return mHost.mFragmentManager;
}
(2)FragmentManagerImpl.beginTransaction()源码
- new BackStackRecord(this)获取的是FragmentTransaction的实现类BackStackRecord(事务管理器)。
@NonNull
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
(3)FragmentTransaction.add()源码
- 在add方法中,系统只做了赋值操作,并没有对Fragment进行任何操作。
- opcmd标记是什么类型的操作
- 将fragment等信息追加到ArrayList列表的末尾。
@NonNull
public FragmentTransaction add(@NonNull Fragment fragment, @Nullable String tag) {
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
@NonNull
public FragmentTransaction add(@IdRes int containerViewId, @NonNull Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}
@NonNull
public FragmentTransaction add(@IdRes int containerViewId, @NonNull Fragment fragment, @Nullable String tag) {
doAddOp(containerViewId, fragment, tag, OP_ADD);
return this;
}
//BackStackRecord.java
@Override
void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
super.doAddOp(containerViewId, fragment, tag, opcmd);
fragment.mFragmentManager = mManager;
}
void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
//code...
addOp(new Op(opcmd, fragment));
}
Op(int cmd, Fragment fragment) {
this.mCmd = cmd;
this.mFragment = fragment;
this.mOldMaxState = Lifecycle.State.RESUMED;
this.mCurrentMaxState = Lifecycle.State.RESUMED;
}
void addOp(Op op) {
mOps.add(op);
op.mEnterAnim = mEnterAnim;
op.mExitAnim = mExitAnim;
op.mPopEnterAnim = mPopEnterAnim;
op.mPopExitAnim = mPopExitAnim;
}
(4)BackStackRecord.commit源码
@Override
public int commit() {
return commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
//code..
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
- mManager.allocBackStackIndex(this):将BackStackRecord添加到mBackStackIndices中。
public int allocBackStackIndex(BackStackRecord bse) {
synchronized (this) {
if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) {
if (mBackStackIndices == null) {
mBackStackIndices = new ArrayList<BackStackRecord>();
}
int index = mBackStackIndices.size();
mBackStackIndices.add(bse);
return index;
} else {
int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1);
mBackStackIndices.set(index, bse);
return index;
}
}
}
- mManager.enqueueAction(this, allowStateLoss):将实现OpGenerator的BackStackRecord添加到了mPendingActions。
public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
//code..
synchronized (this) {
//code..
mPendingActions.add(action);
scheduleCommit();
}
}
//调用handler
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);
updateOnBackPressedCallbackEnabled();
}
}
}
- FragmentManagerImpl.mExecCommit源码
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
public boolean execPendingActions() {
ensureExecReady(true);
boolean didSomething = false;
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
didSomething = true;
}
updateOnBackPressedCallbackEnabled();
doPendingDeferredStart();
burpActive();
return didSomething;
}
- generateOpsForPendingActions(mTmpRecords, mTmpIsPop):将mPendingActions数据添加到mTmpRecords,赋值mTmpIsPop值为false,清空mPendingActions数据并删除handler中的mExecCommit
private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records, ArrayList<Boolean> isPop) {
boolean didSomething = false;
synchronized (this) {
final int numActions = mPendingActions.size();
for (int i = 0; i < numActions; i++) {
didSomething |= mPendingActions.get(i).generateOps(records, isPop);
}
mPendingActions.clear();
mHost.getHandler().removeCallbacks(mExecCommit);
}
return didSomething;
}
@Override
public boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop) {
records.add(this);
isRecordPop.add(false);
if (mAddToBackStack) {
mManager.addBackStackState(this);
}
return true;
}
- removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop):通过调用executeOpsTogether方法来执行添加的所有任务。
- 在moveToState方法中调用FragmentManager中dispatchxxx方法。而这些正好是和activity的生命周期对应起来,也就是说这些方法是随着activity进入到不同的生命周期而被调用的,即mCurState的值是被这些方法触发设置的。
private void removeRedundantOperationsAndExecute(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop) {
//code...
final int numRecords = records.size();
int startIndex = 0;
for (int recordNum = 0; recordNum < numRecords; recordNum++) {
//code...
int reorderingEnd = recordNum + 1;
//code...
executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
startIndex = reorderingEnd;
recordNum = reorderingEnd - 1;
}
//code...
}
//执行添加的所有任务
private void executeOpsTogether(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
//code...
executeOps(records, isRecordPop, startIndex, endIndex);
//code...
}
//入栈或者出栈操作
private static void executeOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
for (int i = startIndex; i < endIndex; i++) {
final BackStackRecord record = records.get(i);
//默认存储为false
final boolean isPop = isRecordPop.get(i);
if (isPop) {
record.bumpBackStackNesting(-1);
boolean moveToState = i == (endIndex - 1);
record.executePopOps(moveToState);
} else {
record.bumpBackStackNesting(1);
record.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.fragment;
if (f != null) {
f.setNextTransition(mTransition, mTransitionStyle);
}
switch (op.cmd) {
case OP_ADD:
f.setNextAnim(op.enterAnim);
mManager.addFragment(f, false);
break;
case OP_REMOVE:
f.setNextAnim(op.exitAnim);
mManager.removeFragment(f);
break;
case OP_HIDE:
f.setNextAnim(op.exitAnim);
mManager.hideFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.enterAnim);
mManager.showFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.exitAnim);
mManager.detachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.enterAnim);
mManager.attachFragment(f);
break;
case OP_SET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(f);
break;
case OP_UNSET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(null);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
}
if (!mReorderingAllowed && op.cmd != OP_ADD && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed) {
mManager.moveToState(mManager.mCurState, true);
}
}
总结
- 通过源码得知add、remove、replacea、hide、show等方法中只是做了赋值操作,并没有对Fragment进行任何操作。
- commit()将FragmentTransaction的实现类BackStackRecord添加到mBackStackIndices集合中。
- 通过enqueueAction()方法将实现OpGenerator的BackStackRecord添加到了mPendingActions中,并通过scheduleCommit方法调用handler.post(mExecCommit)。
- mExecCommit是一个Runnable对象,在run方法中调用execPendingActions()方法。
- execPendingActions()方法将mPendingActions中数据添加到mTmpRecords中,并将mTmpIsPop赋值为false,清空mPendingActions数据并删除handler中mExecCommit对象;通过调用executeOpsTogether方法来执行添加的所有任务。
网友评论