通常情况下我们使用fragment的方式是这样的:
FragmentManager mFragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.add(mContainerViewId, fragment);
fragmentTransaction.commit();
那么Fragment是如果创建的,如何被添加到布局中的呢,我们一起来分析下系统是如何做的。
通过点击add、beginTransaction可以发现都是抽象方法,那么只能通过getFragmentManager()首先获得 FragmentManager:
public FragmentManager getFragmentManager() {
return mFragments.getFragmentManager();
}
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
最终可以获得FragmentManagerImpl这个FragmentMananger实现类。
// FragmentManagerImpl.java
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
// BackStackRecord.java
public FragmentTransaction add(Fragment fragment, String tag) {
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
public FragmentTransaction add(int containerViewId, Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}
public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
doAddOp(containerViewId, fragment, tag, OP_ADD);
return this;
}
最终通过调用BackStackRecord的doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd)方法将fragment加入管理中。
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
fragment.mFragmentManager = mManager;
Op op = new Op();
op.cmd = opcmd;
op.fragment = fragment;
addOp(op);
}
void addOp(Op op) {
if (mHead == null) {
mHead = mTail = op;
} else {
op.prev = mTail;
mTail.next = op;
mTail = op;
}
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
mNumOp++;
}
可以发现在add方法中,系统只做了赋值操作,并没有对fragment进行任何操作,所以应该是在commit中进行操作的:
// BackStackRecord.java
public int commit() {
return commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
if (mCommitted) {
throw new IllegalStateException("commit already called");
}
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Commit: " + this);
LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
PrintWriter pw = new FastPrintWriter(logw, false, 1024);
dump(" ", null, pw, null);
pw.flush();
}
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
// FragmentManager.java
public int allocBackStackIndex(BackStackRecord bse) {
synchronized (this) {
if (mAvailBackStackIndices &#61;&#61; null || mAvailBackStackIndices.size() <&#61; 0) {
if (mBackStackIndices &#61;&#61; null) {
mBackStackIndices &#61; new ArrayList();
}
int index &#61; mBackStackIndices.size();
if (DEBUG) Log.v(TAG, "Setting back stack index " &#43; index &#43; " to " &#43; bse);
mBackStackIndices.add(bse);
return index;
} else {
int index &#61; mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1);
if (DEBUG) Log.v(TAG, "Adding back stack index " &#43; index &#43; " with " &#43; bse);
mBackStackIndices.set(index, bse);
return index;
}
}
}
public void enqueueAction(Runnable action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
mPendingActions.add(action);
if (mPendingActions.size() &#61;&#61; 1) {
mHost.getHandler().removeCallbacks(mExecCommit);
mHost.getHandler().post(mExecCommit);
}
}
}
commit方法最终调用了manager的allocBackStackIndex和enqueueAction方法&#xff0c;其中allocBackStackIndex方法将BackStackRecord添加到了mBackStackIndices中&#xff0c;而enqueueAction方法首先将实现了Runnable的BackStackRecord添加到了mPendingActions,之后调用了handler。
// FragmentManagerImpl.java
Runnable mExecCommit &#61; new Runnable() {
&#64;Override
public void run() {
execPendingActions();
}
};
public boolean execPendingActions() {
while (true) {
int numActions;
synchronized (this) {
numActions &#61; mPendingActions.size();
if (mTmpActions &#61;&#61; null || mTmpActions.length mTmpActions &#61; new Runnable[numActions];
}
mPendingActions.toArray(mTmpActions);
mPendingActions.clear();
mHost.getHandler().removeCallbacks(mExecCommit);
}
mExecutingActions &#61; true;
for (int i&#61;0; i
mTmpActions[i].run();
mTmpActions[i] &#61; null;
}
mExecutingActions &#61; false;
didSomething &#61; true;
}
doPendingDeferredStart();
return didSomething;
}
execPendingActions方法首先将mPendingActions赋值给了mTmpActions,之后通过for循环调用run方法&#xff1a;
// BackStackRecord.java
public void run() {
//代码省略
Op op &#61; mHead;
while (op !&#61; null) {
switch (op.cmd) {
case OP_ADD: {
Fragment f &#61; op.fragment;
f.mNextAnim &#61; op.enterAnim;
mManager.addFragment(f, false);
}
break;
case OP_REPLACE: {
Fragment f &#61; op.fragment;
int containerId &#61; f.mContainerId;
if (mManager.mAdded !&#61; null) {
for (int i &#61; mManager.mAdded.size() - 1; i >&#61; 0; i--) {
Fragment old &#61; mManager.mAdded.get(i);
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG,
"OP_REPLACE: adding&#61;" &#43; f &#43; " old&#61;" &#43; old);
}
if (old.mContainerId &#61;&#61; containerId) {
if (old &#61;&#61; f) {
op.fragment &#61; f &#61; null;
} else {
if (op.removed &#61;&#61; null) {
op.removed &#61; new ArrayList();
}
op.removed.add(old);
old.mNextAnim &#61; op.exitAnim;
if (mAddToBackStack) {
old.mBackStackNesting &#43;&#61; 1;
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Bump nesting of "
&#43; old &#43; " to " &#43; old.mBackStackNesting);
}
}
mManager.removeFragment(old, mTransition, mTransitionStyle);
}
}
}
}
if (f !&#61; null) {
f.mNextAnim &#61; op.enterAnim;
mManager.addFragment(f, false);
}
}
break;
// 代码省略
}
op &#61; op.next;
}
mManager.moveToState(mManager.mCurState, mTransition,
mTransitionStyle, true);
if (mAddToBackStack) {
mManager.addBackStackState(this);
}
}
这个时候就用上了我们之前add方法的opcmd字段&#xff0c;add赋值的字段是OP_ADD&#xff0c;所以可以看到直接调用了mManager.addFragment(f, false)方法&#xff1b;而replace方法赋值的字段是OP_REPLACE&#xff0c;首先调用mManager.removeFragment(old, mTransition, mTransitionStyle)方法将上一个fragment移除&#xff0c;之后再调用mManager.addFragment(f, false)&#xff1a;
public void addFragment(Fragment fragment, boolean moveToStateNow) {
makeActive(fragment);
if (!fragment.mDetached) {
if (mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: " &#43; fragment);
}
mAdded.add(fragment);
fragment.mAdded &#61; true;
fragment.mRemoving &#61; false;
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate &#61; true;
}
if (moveToStateNow) {
moveToState(fragment);
}
}
}
void moveToState(Fragment f) {
moveToState(f, mCurState, 0, 0, false);
}
这个时候调用的moveToState方法就涉及到了Fragment的生命周期&#xff1a;
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
switch (f.mState) {
case Fragment.INITIALIZING:
// fragment的onAttach方法
f.onAttach(mHost.getContext());
if (!f.mRetaining) {
// fragment的onCreate方法
f.performCreate(f.mSavedFragmentState);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState, true);
f.mState &#61; Fragment.CREATED;
}
if (f.mFromLayout) {
// fragment的onCreateView方法
f.mView &#61; f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
if (f.mView !&#61; null) {
f.mView.setSaveFromParentEnabled(false);
if (f.mHidden) f.mView.setVisibility(View.GONE);
// fragment的onViewCreated方法
f.onViewCreated(f.mView, f.mSavedFragmentState);
}
}
//代码省略
}