Fragment源码学习(一)
首先看一下 Fragment 的基本用法
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.frameLayout, Bug5Fragment.newIntance(), Bug5Fragment.class.getName());
transaction.commit();
第一步: getSupportFragmentManager()
首先看一下 getSupportFragmentManager()方法,该方法在 FragmentActivity,可以看到FragmentActivity的间接父类是 Activity
public class FragmentActivity extends ComponentActivity implements
ViewModelStoreOwner,
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompat.RequestPermissionsRequestCodeValidator {
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
}
public class ComponentActivity extends Activity
implements LifecycleOwner, KeyEventDispatcher.Component {
在 FragmentActivity中 getSupportFragmentManager()方法调用了 FragmentController 的 getSupportFragmentManager()方法,而 mFragments 又是FragmentActivity的类成员变量,所以在创建 FragmentActivity类的同时将会调用 createController()方法创建FragmentController实例 mFragments,下面来一张 getSupportFragmentManager的流程图
第二步: beginTransaction()
接下来看 beginTransaction() 的操作流程
public abstract class FragmentManager {
@NonNull
public abstract FragmentTransaction beginTransaction();
FragmentManager 是一个抽象类,它的实现是它的子类 FragmentManagerImpl
/**
* Container for fragments associated with an activity.
*/
final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 {
static boolean DEBUG = false;
static final String TAG = "FragmentManager";
//mPendingActions 表示待执行动作
ArrayList<OpGenerator> mPendingActions;
//mAdded 是 mActive 的子集表示活着的 fragments
final ArrayList<Fragment> mAdded = new ArrayList<>();
//mActive 不仅有活着的 fragments 还有在返回栈中等待被复原的 fragments。
SparseArray<Fragment> mActive;
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
}
可以看到 beginTransaction()方法实际上是直接new了一个 BacStackRecord,BackStackRecord 实现了抽象类 FragmentTransaction
/**
* Entry of an operation on the fragment back stack.
*/
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
static final String TAG = FragmentManagerImpl.TAG;
final FragmentManagerImpl mManager;
//Op类封装了Fragment及其对应的操作指令cmd(add、remove、replace等)
static final class Op {
int cmd;
Fragment fragment;
int enterAnim;
int exitAnim;
int popEnterAnim;
int popExitAnim;
Op() {
}
Op(int cmd, Fragment fragment) {
this.cmd = cmd;
this.fragment = fragment;
}
}
//数组mOps保存了FragmentTransaction的一系列原子操作
//add、remove、replace等
ArrayList<Op> mOps = new ArrayList<>();
//构造函数将FragmentManagerImpl和BackStackRecord绑定
public BackStackRecord(FragmentManagerImpl manager) {
mManager = manager;
}
}
第三步:事务操作 add、remove、replace
接下来看一下FragmentTransaction的 add、remove、replace等一系列原子操作是怎么实现的
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
ArrayList<Op> mOps = new ArrayList<>();
@Override
public FragmentTransaction add(int containerViewId, Fragment fragment, @Nullable String tag) {
doAddOp(containerViewId, fragment, tag, OP_ADD);
return this;
}
@Override
public FragmentTransaction remove(Fragment fragment) {
addOp(new Op(OP_REMOVE, fragment));
return this;
}
@Override
public FragmentTransaction replace(int containerViewId, Fragment fragment,
@Nullable String tag) {
if (containerViewId == 0) {
throw new IllegalArgumentException("Must use non-zero containerViewId");
}
doAddOp(containerViewId, fragment, tag, OP_REPLACE);
return this;
}
private void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
......
fragment.mFragmentManager = mManager;
if (tag != null) {
......
fragment.mTag = tag;
}
if (containerViewId != 0) {
......
fragment.mContainerId = fragment.mFragmentId = containerViewId;
}
addOp(new Op(opcmd, fragment));
}
void addOp(Op op) {
//将一系列FragmentTransacton操作添加到 mOps数组
mOps.add(op);
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
}
}
通过以上源码可以看到 FragmentTransaction的add、remove、replace等方法的逻辑都是一样的,这些方法都没有直接对Fragment进行添加或者删除等操作,而是将我们要操作的Fragment同它的指令cmd封装到一个Op类里,每一个原子操作都会new出一个对应指令的Op对象,最后将这一些列的原子操作对应得Op对象都添加到一个Op数组 mOps 中 ,现在我们可以猜想到真正的add、remove、replace操作应该是在commit方法中,接下来我们看一下commit方法
第四步:commit()
讲 commit()流程之前先了解下 FragmentManangerImpl的几个变量
final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 {
//mPendingActions 待执行动作
ArrayList<OpGenerator> mPendingActions;
//mAdded 是 mActive 的子集表示活着的 fragments
final ArrayList<Fragment> mAdded = new ArrayList<>();
//mActive 不仅有活着的 fragments 还有在返回栈中等待被复原的 fragments。
SparseArray<Fragment> mActive;
//mTmpRecords用来临时存储所有待执行的动作(mPendingActions)生成的 BackStackRecord,
//mTmpIsPop用来存储 BackStackRecord 是否为出栈
ArrayList<BackStackRecord> mTmpRecords;//用于优化执行的临时变量
ArrayList<Boolean> mTmpIsPop;//用于优化执行的临时变量
}
通过commit()方法将一系列事务操作最终交给 FragmentManager 执行
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
final FragmentManagerImpl mManager;
@Override
public int commit() {
return commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
//commit()方法只能够执行一次
if (mCommitted) throw new IllegalStateException("commit already called");
......
mCommitted = true;
if (mAddToBackStack) {
//最终交给FragmentManager执行
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
//最终会交给FragmentManager去执行,这里第一个参数传入BackStackRecord本身
//因为BackStackRecord 实现了接口 OpGenerator
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
}
在 FragmentManger中异步执行 commit()操作
final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 {
public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
......
if (mPendingActions == null) {
mPendingActions = new ArrayList<>();
}
//将待执行的操作添加到mPendingActions数组中
mPendingActions.add(action);
scheduleCommit();//执行commit(这里是异步执行)
}
}
void scheduleCommit() {
synchronized (this) {
boolean postponeReady =
mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
mHost.getHandler().removeCallbacks(mExecCommit);
//获取主线程的Handler通过post方法将要执行的操作加入主线程Looper所在的
//消息队列中,等待执行。
mHost.getHandler().post(mExecCommit);
}
}
}
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
/**
* Only call from main thread!
*/
public boolean execPendingActions() {
ensureExecReady(true);
boolean didSomething = false;
//先将 mPendingActions 数组中的 BackStackRecord对象添加到 mTemRecords 数组
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
//这里会将mOps数组中的一系列命令进行整合
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
didSomething = true;
}
doPendingDeferredStart();
burpActive();
return didSomething;
}
}
看一下 generateOpsForPendingActions(mTmpRecords, mTmpIsPop) 具体执行了什么
private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isPop) {
boolean didSomething = false;
synchronized (this) {
if (mPendingActions == null || mPendingActions.size() == 0) {
return false;
}
final int numActions = mPendingActions.size();
for (int i = 0; i < numActions; i++) {
//最终会调用 BackStackRecord的 generateOps()方法
//注意:这里didSomething将始终返回true!
didSomething |= mPendingActions.get(i).generateOps(records, isPop);
}
mPendingActions.clear();
mHost.getHandler().removeCallbacks(mExecCommit);
}
return didSomething;
}
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
@Override
public boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop) {
//将 BackStackRecord添加到 mTmpRecords 数组中
records.add(this);
isRecordPop.add(false);
if (mAddToBackStack) {
mManager.addBackStackState(this);
}
return true;
}
}
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop)方法最终会执行到 FragmentManagerImpl 的 executeOpsTogether 方法
private void executeOpsTogether(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
final boolean allowReordering = records.get(startIndex).mReorderingAllowed;
boolean addToBackStack = false;
if (mTmpAddedFragments == null) {
mTmpAddedFragments = new ArrayList<>();
} else {
mTmpAddedFragments.clear();
}
//将当前所有活着的 fragments 添加到mTempAddedFragments数组中
mTmpAddedFragments.addAll(mAdded);
Fragment oldPrimaryNav = getPrimaryNavigationFragment();
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
final BackStackRecord record = records.get(recordNum);
final boolean isPop = isRecordPop.get(recordNum);
if (!isPop) {
//expandOps()方法将对指令进行整合,重点关注replace
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);
}
//该方法才会真正地执行 Op 指令(add、remove等)
executeOps(records, isRecordPop, startIndex, endIndex);
......
}
最后看一下Op指令(add、remove、replace等)的整合与执行操作
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
//mOps保存了所有事务操作
ArrayList<Op> mOps = new ArrayList<>();
Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
for (int opNum = 0; opNum < mOps.size(); opNum++) {
//第一层循环遍历mOps数组中所有的Op对象
final Op op = mOps.get(opNum);
switch (op.cmd) {
......
case OP_REPLACE: {
//获取Op对象里需要执行replace操作的Fragment
final Fragment f = op.fragment;
//获取对应Fragment的父容器id
final int containerId = f.mContainerId;
//标记该Fragment是否已经被添加
boolean alreadyAdded = false;
for (int i = added.size() - 1; i >= 0; i--) {
final Fragment old = added.get(i);
if (old.mContainerId == containerId) {
if (old == f) {
//id为mContainerId 的父容器中如果已经添加过了该Fragment
//就将标记位置为true
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;
}
//如果父容器中尚未添加该Fragment就new出一个
//指令cmd为remove的Op对象,将该对象插入到opNum处
final Op removeOp = new Op(OP_REMOVE, old);
removeOp.enterAnim = op.enterAnim;
removeOp.popEnterAnim = op.popEnterAnim;
removeOp.exitAnim = op.exitAnim;
removeOp.popExitAnim = op.popExitAnim;
mOps.add(opNum, removeOp);
added.remove(old);
opNum++;
}
}
}
if (alreadyAdded) {
//如果该Fragment已经添加就直接将该Op对象(指令为replace)移除
mOps.remove(opNum);
opNum--;
} else {
//如果该Fragment没有添加将对应的replace指令改为add
//注意在该replace指令前已经添加了一个包含remove指令的Op对象
//所以最终执行的操作是先 remove 再 add
op.cmd = OP_ADD;
added.add(f);
}
}
break;
case OP_SET_PRIMARY_NAV: {
......
}
break;
}
}
return oldPrimaryNav;
}
}