==本文所引用的代碼均爲support-v4-23.0.1包中的源碼,使用‘…’表示省略部分代碼。==
當在Activity的onCreate方法中通過一下方式添加Fragment,運行程序,便可以修飾在屏幕上。
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(resId, fragmentA);
transaction.commit();
這幾行代碼讓Fragment經歷了怎樣的一番旅途,最終被關聯到宿主Activity並顯示。我準備扒一扒support-v4-23.0.0的源碼,探索這一段神奇的旅途。
一 相關的類
與此相關的類主要有10個,分別爲:
FragmentManger爲抽象類,定義對Fragment的操作行爲,子類爲FragmentMangerImpl。FragmentMangerImpl又實現了LayoutInflaterFactory接口,是真正對Fragment執行初始化,顯示和移除等等操作的類。
FragmentTransaction爲抽象類,定義對Fragment操作事務行爲,子類爲BackStackRecord。BackStackRecord又實現了Runnable和FragmentManger.BackStackEntry接口,是執行Fragment添加,顯示,隱藏和移除等等事務的類。Op爲BackStackRecord的靜態內部類,當使用FragmentTransaction添加,替換,隱藏,移除等等操作便會在BackStackRecord對象中生成一個記錄操作行爲和Fragment的Op對象,該對象以鏈表的方式存儲在BackStackRecord中。
FragmentHostCallback爲抽象類,又繼承了FragmentContainer,子類爲FragmentActivity的內部類HostCallback。
FragmentController封裝對FragmentMangerImpl和HostCallback獲取和操作的方法。
FragmentActivity用作Fragment的容器。
類圖(Fragment的全家福):
流程分析
一,獲取FragmentManager
在我們自定義的Activity中經常使用使用getSupportFragmentManager方法獲取當前的FragmentManager(即FragmentMagagerImpl對象),那就先看看FragmentActivity類中的代碼:
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
mFragments是什麼類型,何時初始化與賦值?接着往FragmentActivity中查看:
//在對象創建是便已賦值
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
創建HostCallbacks對象,那就看看它的構造方法代碼:
public HostCallbacks() {
//調用父類FragmentHostCallback的構造方法進行初始化
super(FragmentActivity.this /*fragmentActivity*/);
}
接着繼續看FragmentHostCallback代碼:
public abstract class FragmentHostCallback<E> extends FragmentContainer {
//當前關聯的FragmentActivity對象
private final Activity mActivity;
//當前關聯的Context對象,其實就是FragmentActivity對象
final Context mContext;
//當前FragmentActivity的mHandler屬性
private final Handler mHandler;
final int mWindowAnimations;
//FragmentActivity獲取的FragmentManager就是這個屬性
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
//當前key爲who,value爲加載器LoaderManagerImpl
private SimpleArrayMap<String, LoaderManager> mAllLoaderManagers;
//
private LoaderManagerImpl mLoaderManager;
private boolean mCheckedForLoaderManager;
private boolean mLoadersStarted;
public FragmentHostCallback(Context context, Handler handler, int windowAnimations) {
this(null /*activity*/, context, handler, windowAnimations);
}
//FragmentActivity的內部類HostCallbacks調用賦值的構造方法
FragmentHostCallback(FragmentActivity activity) {
//使用activity給mContext賦值,activity.mHandler給mHandler賦值
this(activity, activity /*context*/, activity.mHandler, 0 /*windowAnimations*/);
}
//執行賦值
FragmentHostCallback(Activity activity, Context context, Handler handler, int windowAnimations) {
Activity = activity;
mContext = context;
mHandler = handler;
mWindowAnimations = windowAnimations;
}
...
}
再往回看看FragmentActivity的onCreate方法:
protected void onCreate(@Nullable Bundle savedInstanceState) {
//**這一步很重要**
//將FragmentController的mHost賦值給HostCallBack的mFragmentManager,便完成了當前Activity與FramgmentManger關聯。
mFragments.attachHost(null /*parent*/);
super.onCreate(savedInstanceState);
NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
mFragments.restoreLoaderNonConfig(nc.loaders);
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
}
//通知mFragmentManager當前Activity執行了onCreate
mFragments.dispatchCreate();
}
FragmentController中attachHost和dispatchCreate方法代碼:
public void attachHost(Fragment parent) {
mHost.mFragmentManager.attachController(mHost, mHost /*container*/, parent);
}
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
調用FragmentManagerImpl相關方法和屬性的代碼:
public void attachController(FragmentHostCallback host, FragmentContainer container, Fragment parent) {
if (mHost != null) throw new IllegalStateException("Already attached");
//將FragmentController中的mHost賦值給FragmentManagerImpl的mHost,自此便完成當前Activity與FramgmentManger關聯
mHost = host;
mContainer = container;
mParent = parent;
}
//FragmentManagerImpl當前狀態值,默認爲初始化
int mCurState = Fragment.INITIALIZING;
public void dispatchCreate() {
mStateSaved = false;
//更新當前狀態mCurState爲Fragment.CREATED
moveToState(Fragment.CREATED, false);
}
void moveToState(int newState, boolean always) {
moveToState(newState, 0, 0, always);
}
void moveToState(int newState, int transit, int transitStyle, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No host");
}
if (!always && mCurState == newState) {
return;
}
//更新當前狀態mCurState爲Fragment.CREATED
mCurState = newState;
//當從FragmentActivity的onCreate執行到此時,由於還未有添加Fragment,則mActive爲null,便返回。
//執行完這些代碼後,FragmentManagerImpl的mCurState爲Fragment.CREATED
if (mActive != null) {
boolean loadersRunning = false;
for (int i=0; i<mActive.size(); i++) {
Fragment f = mActive.get(i);
if (f != null) {
moveToState(f, newState, transit, transitStyle, false);
...
}
}
...
}
}
當Activity的onCreate方法執行完super.onCreate(),我們便能夠通過getSupportFragmentManager方法獲取到一個可以正常使用的FragmentManagerImpl對象。
二,獲取FragmentTransaction
調用FragmentManager的beginTransaction()方法獲取FragmentTransaction。看看代碼,究竟執行了哪些操作。
public FragmentTransaction beginTransaction() {
//創建了一個BackStackRecord對象,並把自己作爲參數傳遞給它。
return new BackStackRecord(this);
}
public BackStackRecord(FragmentManagerImpl manager){
//對mManager進行賦值,完成BackStackRecord與FragmentManagerImpl關聯
mManager = manager;
}
三,添加Fragment
調用FragmentTransaction的add方法添加Fragment又執行了BackStackRecord哪些方法?繼續看代碼:
//添加Fragment並綁定tag
public FragmentTransaction add(Fragment fragment, String tag) {
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
//向指定id的View作爲容器,添加Fragment
public FragmentTransaction add(int containerViewId, Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}
//指定View容器和tag,添加Fragment
public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
doAddOp(containerViewId, fragment, tag, OP_ADD);
return this;
}
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
//將與Activity關聯的FragmentMangerImpl對象賦值給Fragment
fragment.mFragmentManager = mManager;
//如果Fragment的tag屬性已賦值,則添加時指定的tag必須要與其相同
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;
}
//如果Fagment已關聯顯示容器的Id(即在View中顯示),則添加時不能添加到其他的View
if (containerViewId != 0) {
if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
throw new IllegalStateException("Can't change container ID of fragment "
+ fragment + ": was " + fragment.mFragmentId
+ " now " + containerViewId);
}
fragment.mContainerId = fragment.mFragmentId = containerViewId;
}
//創建Op,指定執行操作類型和關聯Fragment
Op op = new Op();
op.cmd = opcmd;
op.fragment = fragment;
addOp(op);
}
//將Op對象加入到Op鏈表中
void addOp(Op op) {
if (mHead == null) {
mHead = mTail = op;
} else {
//加入到Op鏈表尾部
op.prev = mTail;
mTail.next = op;
mTail = op;
}
...
mNumOp++;
}
自此Fragment便被添加到FragmentTransaction(即BackStackRecord對象中)。
四,提交Fragment添加事務
調用FragmentTransaction的commit方法,便提交Fragment的添加事務。我們只要運行代碼,Fragment便會顯示在屏幕上。commit操作執行了哪些方法,commit之後Actvity執行onStart和onResume時Fragment又經歷了哪些操作。繼續看代碼分析。
public int commit() {
return commitInternal(false);
}
public int commitAllowingStateLoss() {
return commitInternal(true);
}
int commitInternal(boolean allowStateLoss) {
if (mCommitted) throw new IllegalStateException("commit already called");
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Commit: " + this);
LogWriter logw = new LogWriter(TAG);
PrintWriter pw = new PrintWriter(logw);
dump(" ", null, pw, null);
}
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
//將創建的BackStackRecord對象,提交給FragmentManagerImpl
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
因爲BackStackRecord實現了Runnable,故在FragmentManagerImpl定義一個ArrayList類型的集合mPendingActions來存儲添加的BackStackRecord對象。在看看enqueueAction以及與其相關的方法和屬性的代碼:
private void checkStateLoss() {
//如果在已執行了保存狀態信息操作後執行commit,則拋出異常
if (mStateSaved) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
if (mNoTransactionsBecause != null) {
throw new IllegalStateException(
"Can not perform this action inside of " + mNoTransactionsBecause);
}
}
public void enqueueAction(Runnable 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<Runnable>();
}
//將提交的BackStackRecord添加到集合中
mPendingActions.add(action);
if (mPendingActions.size() == 1) {
//移除還未執行的Runnalbe:mExecCommit
mHost.getHandler().removeCallbacks(mExecCommit);
//發送一個延時執行的Runnalbe:mExecCommit
mHost.getHandler().post(mExecCommit);
}
}
}
//延時執行的Runnable對象
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
//運行mPendingActions中的Runnable對象
execPendingActions();
}
};
從enqueueAction中第一個判斷的checkStateLoss方法代碼可知:不能在Activity執行onSaveInstanceState操作後再調用commit。如果提交的Fragment顯示重要的信息,建議也儘量不要使用commitAllowingStateLoss。因爲執行onSaveInstanceState時會保存所有Fragment的狀態信息 ,在其後執行commitAllowingStateLoss則會丟失提交的Fragment信息,導致狀態恢復時出現一些很奇怪的現象。
執行commit提交的BackStackRecord在enqueueAction方法裏並沒有被直接執行,而是存儲在mPendingActions中等待執行。同時,會移除正在Message隊列中等待執行的mExecCommit,並使用FragmentActivity的mHandler發送新的的延時執行信息mExecCommit。mExecCommit的run方法調用了execPendingActions,也就是說真正執行BackStackRecord的是execPendingActions。execPendingActions方法中有一個while(true)循環來遍歷mPendingActions中的Runnable並執行run方法,直至mPendingActions爲空集合才退出。
execPendingActions方法代碼:
/**
* Only call from main thread!
*/
public boolean execPendingActions() {
if (mExecutingActions) {
throw new IllegalStateException("Recursive entry to executePendingTransactions");
}
//不能在非主線程中調用此方法
if (Looper.myLooper() != mHost.getHandler().getLooper()) {
throw new IllegalStateException("Must be called from main thread of process");
}
boolean didSomething = false;
//採用無限循環可以讓在執行execPendingActions時提交的BackStackRecord被及時執行run方法。
while (true) {
int numActions;
synchronized (this) {
//如果mPendingActions爲null(即未提交BackStackRecord),或mPendingActions爲空集合(即所有的BackStackRecord都執行完),則退出循環。
if (mPendingActions == null || mPendingActions.size() == 0) {
break;
}
numActions = mPendingActions.size();
if (mTmpActions == null || mTmpActions.length < numActions) {
mTmpActions = new Runnable[numActions];
}
//將mPendingActions集合中的數據存儲到mTmpActions數組
mPendingActions.toArray(mTmpActions);
//清空集合
mPendingActions.clear();
//移除延時執行消息
mHost.getHandler().removeCallbacks(mExecCommit);
}
mExecutingActions = true;
for (int i=0; i<numActions; i++) {
//**這一步執行很重要**
//執行BackStackRecord的run方法
mTmpActions[i].run();
mTmpActions[i] = null;
}
mExecutingActions = false;
didSomething = true;
}
...
return didSomething;
}
關鍵步驟mTmpActions[i].run()執行的是BackStackRecord的run方法。其代碼:
public void run() {
...
//循環執行Op鏈表中的Op對象
Op op = mHead;
while (op != null) {
int enterAnim = state != null ? 0 : op.enterAnim;
int exitAnim = state != null ? 0 : op.exitAnim;
switch (op.cmd) {
//添加Fragment
case OP_ADD: {
Fragment f = op.fragment;
f.mNextAnim = enterAnim;
mManager.addFragment(f, false);
} break;
//替換Fragment
case OP_REPLACE: {
Fragment f = op.fragment;
int containerId = f.mContainerId;
if (mManager.mAdded != null) {
for (int i=0; i<mManager.mAdded.size(); i++) {
Fragment old = mManager.mAdded.get(i);
if (FragmentManagerImpl.DEBUG) Log.v(TAG,
"OP_REPLACE: adding=" + f + " old=" + old);
if (old.mContainerId == containerId) {
if (old == f) {
op.fragment = f = null;
} else {
if (op.removed == null) {
op.removed = new ArrayList<Fragment>();
}
op.removed.add(old);
old.mNextAnim = exitAnim;
if (mAddToBackStack) {
old.mBackStackNesting += 1;
if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
+ old + " to " + old.mBackStackNesting);
}
mManager.removeFragment(old, transition, transitionStyle);
}
}
}
}
if (f != null) {
f.mNextAnim = enterAnim;
mManager.addFragment(f, false);
}
} break;
//
case OP_REMOVE: {
Fragment f = op.fragment;
f.mNextAnim = exitAnim;
mManager.removeFragment(f, transition, transitionStyle);
} break;
//隱藏Fragment
case OP_HIDE: {
Fragment f = op.fragment;
f.mNextAnim = exitAnim;
mManager.hideFragment(f, transition, transitionStyle);
} break;
//顯示Fragment
case OP_SHOW: {
Fragment f = op.fragment;
f.mNextAnim = enterAnim;
mManager.showFragment(f, transition, transitionStyle);
} break;
//detach Fragment
case OP_DETACH: {
Fragment f = op.fragment;
f.mNextAnim = exitAnim;
mManager.detachFragment(f, transition, transitionStyle);
} break;
//attach Fragment
case OP_ATTACH: {
Fragment f = op.fragment;
f.mNextAnim = enterAnim;
mManager.attachFragment(f, transition, transitionStyle);
} break;
default: {
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
}
}
//執行下一個Op對象
op = op.next;
}
//調用FragmentManagerImpl的moveToState,更新當前Fragment狀態
mManager.moveToState(mManager.mCurState, transition, transitionStyle, true);
...
}
使用FragmentTransaction的add方法添加Fragment時,會創建Op對象,cmd爲OP_ADD。執行到此run方法時,則會進入case OP_ADD,在其中調用了FragmentManagerImpl的addFragment方法添加提交的Fragment。回顧一下之前FragmentActivity的onCreate中的介紹,當我們在Activity的onCreate方法代碼super.onCreate後調用getSupportFragmentManager時,與Actvity關聯的FragmentManagerImpl對象的mCurState已被更新爲Fragment.CREATED。此時被提交的fragment的mState屬性還是Fragment.INITIALIZING默認值。
繼續查看FragmentManagerImpl的addFragment方法和與其相關聯的makeActive方法代碼:
void makeActive(Fragment f) {
if (f.mIndex >= 0) {
return;
}
if (mAvailIndices == null || mAvailIndices.size() <= 0) {
if (mActive == null) {
mActive = new ArrayList<Fragment>();
}
//設置其位置和父Fragment(在Activity中添加的,mParent爲null;只有在Fragment中添加的纔有Parent Fragment)。
f.setIndex(mActive.size(), mParent);
//添加到mActive集合中
mActive.add(f);
} else {
//更新信息
f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1), mParent);
mActive.set(f.mIndex, f);
}
...
}
public void addFragment(Fragment fragment, boolean moveToStateNow) {
if (mAdded == null) {
mAdded = new ArrayList<Fragment>();
}
if (DEBUG) Log.v(TAG, "add: " + fragment);
//添加到mActive或更新信息
makeActive(fragment);
if (!fragment.mDetached) {
//如果已添加到mAdd,則拋出異常
if (mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: " + fragment);
}
//添加到mAdded
mAdded.add(fragment);
//修改標誌mAdded爲true(即已添加)
fragment.mAdded = true;
fragment.mRemoving = false;
...
if (moveToStateNow) {
//更新fragment狀態,並執行相應操作
moveToState(fragment);
}
}
}
因爲BackStackRecord的run方法中case OP_ADD代碼塊中的addFragment的moveToStateNow爲false,所以if (moveToStateNow)不成立,即不會進入moveToState(fragment)。待BackStackRecord的run方法中的Op鏈表的數據被執行完,便會執行底部代碼:mManager.moveToState(mManager.mCurState, transition, transitionStyle, true)。此時mManager.mCurState爲Fragment.CREATED,而fragment.mState爲Fragment.INITIALIZING。
初始化Fragment:
void moveToState(int newState, int transit, int transitStyle, boolean always) {
…
mCurState = newState;
if (mActive != null) {
boolean loadersRunning = false;
//遍歷mActive集合
for (int i=0; i<mActive.size(); i++) {
//獲取Fragment
Fragment f = mActive.get(i);
if (f != null) {
//執行更新操作並更新f.mState
moveToState(f, newState, transit, transitStyle, false);
…
}
}
…
}
}
調用mManager.moveToState傳入newState值與mCurState相同,mCurState值沒有被改變。執行moveToState(f, newState, transit, transitStyle, false)代碼。還是繼續看代碼,分析。
先看看Fragment的幾種狀態值:
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
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.
當前FragmentManagerImpl的mCurState爲Fragment.CREATED(即1),而mAtive中的Fragment的mState爲Fragment.INITIALIZING(即0)。
void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) {
...
if (f.mState < newState) {
// For fragments that are created from a layout, when restoring from
// state we don't want to allow them to be created until they are
// being reloaded from the layout.
//如果f是從佈局文件創建的,當恢復狀態時,沒有執行執行從佈局重新加載操作,則返回
if (f.mFromLayout && !f.mInLayout) {
return;
}
...
switch (f.mState) {
//執行Fragment初始化
case Fragment.INITIALIZING:
//如果有保存狀態信息,則恢復
if (f.mSavedFragmentState != null) {
f.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader());
f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
FragmentManagerImpl.VIEW_STATE_TAG);
f.mTarget = getFragment(f.mSavedFragmentState,
FragmentManagerImpl.TARGET_STATE_TAG);
if (f.mTarget != null) {
f.mTargetRequestCode = f.mSavedFragmentState.getInt(
FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
}
f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
if (!f.mUserVisibleHint) {
f.mDeferStart = true;
if (newState > Fragment.STOPPED) {
newState = Fragment.STOPPED;
}
}
}
//mHost賦值FragemntContooler,即與Activity關聯
f.mHost = mHost;
//設置父Fragemnt(默認爲null,只有子Fragemnt纔有值)
f.mParentFragment = mParent;
//關聯FragmentManagerImpl
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
f.mCalled = false;
f.onAttach(mHost.getContext());
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onAttach()");
}
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
}
if (!f.mRetaining) {
f.performCreate(f.mSavedFragmentState);
}
f.mRetaining = false;
//從佈局文件創建的Fragemnt
if (f.mFromLayout) {
// For fragments that are part of the content view
// layout, we need to instantiate the view immediately
// and the inflater will take care of adding it.
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
if (Build.VERSION.SDK_INT >= 11) {
ViewCompat.setSaveFromParentEnabled(f.mView, false);
} else {
f.mView = NoSaveStateFrameLayout.wrap(f.mView);
}
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);
} else {
f.mInnerView = null;
}
}
//創建Fragment的View
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
//非佈局文件創建,即直接new
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
container = (ViewGroup)mContainer.onFindViewById(f.mContainerId);
if (container == null && !f.mRestored) {
throwException(new IllegalArgumentException(
"No view found for id 0x"
+ Integer.toHexString(f.mContainerId) + " ("
+ f.getResources().getResourceName(f.mContainerId)
+ ") for fragment " + f));
}
}
f.mContainer = container;
//執行創建View
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
if (Build.VERSION.SDK_INT >= 11) {
ViewCompat.setSaveFromParentEnabled(f.mView, false);
} else {
f.mView = NoSaveStateFrameLayout.wrap(f.mView);
}
if (container != null) {
Animation anim = loadAnimation(f, transit, true,
transitionStyle);
if (anim != null) {
setHWLayerAnimListenerIfAlpha(f.mView, anim);
f.mView.startAnimation(anim);
}
container.addView(f.mView);
}
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);
} else {
f.mInnerView = null;
}
}
f.performActivityCreated(f.mSavedFragmentState);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
//執行Fragment的start操作
case Fragment.ACTIVITY_CREATED:
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.performStart();
}
//顯示Fragemnt
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
f.mResumed = true;
f.performResume();
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
} else if (f.mState > newState) {
...
}
//更新fragment的mState值
f.mState = newState;
}
執行moveToState(f, newState, transit, transitStyle, false)代碼時,傳入的newState爲1,而f.mState爲0,則進入case Fragment.INITIALIZING代碼塊。待執行完Fragment.INITIALIZING代碼塊,由於f.mState值比Fragment.CREATED,Fragment.ACTIVITY_CREATED,Fragment.STOPPED和Fragment.STARTED都小,則無法進入這些代碼塊。最終執行f.mState = newState,更新f.mState爲Fragment.CREATED。
到此時Activity的代碼也剛執行完onCreate,接着執行onStart,onResume並顯示。接着看FragemntActivity中的這些方法代碼:
final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
...
case MSG_RESUME_PENDING:
onResumeFragments();
//遍歷並執行execPendingActions中BackStackRecord
mFragments.execPendingActions();
break;
default:
super.handleMessage(msg);
}
}
};
protected void onStart() {
super.onStart();
...
if (!mCreated) {
mCreated = true;
//更新狀態爲ActivityCreated
mFragments.dispatchActivityCreated();
}
mFragments.noteStateNotSaved();
//遍歷並執行execPendingActions中BackStackRecord
mFragments.execPendingActions();
mFragments.doLoaderStart();
//更新狀態爲Start
mFragments.dispatchStart();
mFragments.reportLoaderStart();
}
protected void onResume() {
super.onResume();
//發送執行execPendingActions消息
mHandler.sendEmptyMessage(MSG_RESUME_PENDING);
mResumed = true;
//遍歷並執行execPendingActions中BackStackRecord
mFragments.execPendingActions();
}
FragmentController中execPendingActions,dispatchActivityCreated和dispatchStart代碼:
public void dispatchActivityCreated() {
mHost.mFragmentManager.dispatchActivityCreated();
}
public void dispatchStart() {
mHost.mFragmentManager.dispatchStart();
}
public void dispatchResume() {
mHost.mFragmentManager.dispatchResume();
}
public boolean execPendingActions() {
return mHost.mFragmentManager.execPendingActions();
}
FragmentController並沒有做什麼事情,而是FragmentManagerImpl執行了對應的操作。再看看FragmentManagerImpl中這些方法的代碼。execPendingActions方法代碼在上文有展示,此處便不再列出。
public void dispatchActivityCreated() {
mStateSaved = false;
moveToState(Fragment.ACTIVITY_CREATED, false);
}
public void dispatchStart() {
mStateSaved = false;
moveToState(Fragment.STARTED, false);
}
public void dispatchResume() {
mStateSaved = false;
moveToState(Fragment.RESUMED, false);
}
當執行moveToState(Fragment.ACTIVITY_CREATED, false), 則FragmentManagerImpl的mCurState更新爲ACTIVITY_CREATED,Fragment便會進入到case Fragment.CREATED代碼塊,執行create相關操作。依次類推Activity執行onResume,fragment執行performResume()即可以顯示在屏幕上。
Fragment添加子Fragment
使用getChildFragmentManager獲取FragmentManager。
final public FragmentManager getChildFragmentManager() {
if (mChildFragmentManager == null) {
instantiateChildFragmentManager();
if (mState >= RESUMED) {
mChildFragmentManager.dispatchResume();
} else if (mState >= STARTED) {
mChildFragmentManager.dispatchStart();
} else if (mState >= ACTIVITY_CREATED) {
mChildFragmentManager.dispatchActivityCreated();
} else if (mState >= CREATED) {
mChildFragmentManager.dispatchCreate();
}
}
return mChildFragmentManager;
}
void instantiateChildFragmentManager() {
mChildFragmentManager = new FragmentManagerImpl();
mChildFragmentManager.attachController(mHost, new FragmentContainer() {
@Override
@Nullable
public View onFindViewById(int id) {
if (mView == null) {
throw new IllegalStateException("Fragment does not have a view");
}
return mView.findViewById(id);
}
@Override
public boolean onHasView() {
return (mView != null);
}
}, this);
}
管理子Fragment的mChildFragmentManager的mHost與Activity中mHost是同一個對象。調用getChildFragmentManager方法時,也會更新mChildFragmentManager的mCurState狀態和子Fragment的狀態。更新流程與上文所講述的一致。