最近在開發(fā)過程中發(fā)現(xiàn)自己對Fragment的管理原理理解的很模糊,于是以Android-28為基礎(chǔ),對Fragment的管理做了一下簡單梳理,記錄在此,方便后面查閱则果。
本文主要弄清下面幾個(gè)問題:
- Transation()到底做了什么事情
- Replace()操作,Fragment到底是什么顯示出來的蓄坏。
- popBackStack()上一個(gè)Fragment是如何恢復(fù)的董习。
一榔袋、事務(wù)Transation到底做了哪些事情
首先明確一點(diǎn):所有可以使用Fragment的Activity都是FragmentActivity的子類。因?yàn)橹挥性贔ragmentActivity中才有FragmentManager铡俐。而Fragment是由FragmentManager來管理的凰兑。
getFragmentManager()獲取到的FragmentManager支持原生的Fragment,
getSupportFragmentManager()支持的是v4包的Fragment审丘。
1.1 FragmentManagerImpl 是 FragmentManager的實(shí)現(xiàn)類
在FragmentAactivity這個(gè)類下面吏够,當(dāng)我們調(diào)用getSupportManager的時(shí)候
public class FragmentActivity extends BaseFragmentActivityJB implements
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompatApi23.RequestPermissionsRequestCodeValidator {
···
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
···
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
···
}
我們可以看到FragmentActivity里面有一個(gè)FragmentController,這個(gè)FragmentController定義了所有對Fragment的管理操作滩报,包括我們的Activity在onCreate锅知,onResume,onDestroy等各種生命周期或回調(diào)對Fragment的影響脓钾,都是由這個(gè)類來控制的售睹。
public class FragmentController {
private final FragmentHostCallback<?> mHost;
/**
* Returns a {@link FragmentController}.
*/
public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
return new FragmentController(callbacks);
}
/**
* Returns a {@link FragmentManager} for this controller.
*/
public FragmentManager getSupportFragmentManager() {
//獲取到FragmentManager對象
return mHost.getFragmentManagerImpl();
}
FragmentHostCallback是一個(gè)抽象類,負(fù)責(zé)調(diào)用各種各樣的回調(diào)可训。
HostCallbacks是FragmentActivity里面的一個(gè)繼承FragmentHostCallback的內(nèi)部類昌妹。下面我們來看看FragmentHostCallback的默認(rèn)實(shí)現(xiàn)
public abstract class FragmentHostCallback<E> extends FragmentContainer {
private final Activity mActivity;
···
// 實(shí)例化FragmentManager對象,F(xiàn)ragmentManagerImpl是繼承自FragmentManager抽象類的握截,對FragmentManager的各種方法提供具體實(shí)現(xiàn)
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
···
}
至此我們找到了Fragment的實(shí)現(xiàn)類FragmentManagerImpl
FragmentManagerImpl里面的具體實(shí)現(xiàn)就是有關(guān)Fragment是如何運(yùn)行的飞崖,各種各樣的生命周期弧圆,判斷Fragment的不同狀態(tài)昆庇,切換狀態(tài),Transaction只是用作記錄對Fragment的操作記錄砰逻,最終調(diào)用commit的時(shí)候畜眨,實(shí)際上調(diào)用的還是FragmentManagerImpl的方法
1.2、 FragmentTransaction 是操作Fragment的橋梁术瓮。
每次我們對Fragment進(jìn)行操作 都是通過FragmentTransaction這個(gè)類來實(shí)現(xiàn)康聂。
FragmentTransaction的一些常用使用方式:
//添加Fragment到FragmentList中
private void addFragment(Fragment fragment, String tag){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.fragment_container,fragment,tag);
transaction.commit();
}
// 清空fragmentList的所有Fragment,替換成新的Fragment胞四,注意Fragment里面的坑
private void replaceFragment(Fragment fragment, String tag){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment_container,fragment,tag);
transaction.commit();
}
//移除指定的Fragment
private void removeFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment);
transaction.commit();
}
//把Fragment設(shè)置成顯示狀態(tài)恬汁,但是并沒有添加到FragmentList中
private void showFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.show(fragment);
transaction.commit();
}
//把Fragment設(shè)置成顯示狀態(tài),但是并沒有添加到FragmentList中
private void hideFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.hide(fragment);
transaction.commit();
}
// 效果和show相近辜伟,創(chuàng)建視圖氓侧,添加到containerid指定的Added列表,F(xiàn)ragmentList依然保留导狡,但是會(huì)引起生命周期的變化
private void attachFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.attach(fragment);
transaction.commit();
}
// 效果和hide相近约巷,清除視圖,從containerid指定的Added列表移除旱捧,F(xiàn)ragmentList依然保留独郎,但是會(huì)引起生命周期的變化
private void detachFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.detach(fragment);
transaction.commit();
}
核心敲重點(diǎn):
Transaction只是用作記錄對Fragment的操作記錄踩麦,最終調(diào)用commit的時(shí)候,實(shí)際上調(diào)用的還是FragmentManagerImpl的方法
FragmentManager.beginTransaction() 返回的是一個(gè)BackStackRecord的實(shí)例,而BackStackRecord繼承自FragmentTransaction
// FragmentManager 的實(shí)現(xiàn)類
final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
···
@Override
public FragmentTransaction beginTransaction() {
// 每次的FragmentTransaction都是獨(dú)立的
return new BackStackRecord(this);
}
···
}
// Transaction的實(shí)現(xiàn)類
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
// 初始化的時(shí)候傳入FragmentManagerImpl 的實(shí)例
public BackStackRecord(FragmentManagerImpl manager) {
mManager = manager;
}
@Override
public int commit() {
//返回棧id氓癌,要是不添加進(jìn)棧谓谦,返回-1
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(TAG);
PrintWriter pw = new PrintWriter(logw);
dump(" ", null, pw, null);
}
mCommitted = true;
//是否要添加到回退棧
if (mAddToBackStack) {
// 在回退棧中分配棧ID
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
//執(zhí)行這個(gè)Transaction
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
}
FragmentTransaction 支持一系列的操作
#將一個(gè)fragment實(shí)例添加到Activity里面指定id的容器中
add(Fragment fragment, String tag)
add(int containerViewId, Fragment fragment)
add(int containerViewId, Fragment fragment, String tag);
#將一個(gè)fragment實(shí)例從FragmentManager的FragmentList中移除
remove(Fragment fragment);
#只控制Fragment的隱藏
hide(Fragment fragment)
#只控制Fragment的顯示
show(Fragment fragment)
#清除視圖,從containerid指定的Added列表移除贪婉,F(xiàn)ragmentList依然保留
detach(Fragment fragment)
#創(chuàng)建視圖反粥,添加到containerid指定的Added列表,F(xiàn)ragmentList依然保留
attach(Fragment fragment)
#替換containerViewId中的fragment疲迂,它會(huì)把containerViewId中所有fragment刪除才顿,然后添加當(dāng)前的fragment
replace(int containerViewId, Fragment fragment)
replace(int containerViewId, Fragment fragment, String tag)
FragmentTransaction 其實(shí)就是一個(gè)容器,內(nèi)部維護(hù)一個(gè)mOps數(shù)組,執(zhí)行add(),remove(),replace()操作時(shí),所做的就是講這些操作封裝成Op對象保存在mOps數(shù)組中。
public abstract class FragmentTransaction {
static final int OP_NULL = 0;
static final int OP_ADD = 1;
static final int OP_REPLACE = 2;
static final int OP_REMOVE = 3;
static final int OP_HIDE = 4;
static final int OP_SHOW = 5;
static final int OP_DETACH = 6;
static final int OP_ATTACH = 7;
static final int OP_SET_PRIMARY_NAV = 8;
static final int OP_UNSET_PRIMARY_NAV = 9;
static final int OP_SET_MAX_LIFECYCLE = 10;
static final class Op {
int mCmd;
Fragment mFragment;
Op() {
}
Op(int cmd, Fragment fragment) {
this.mCmd = cmd;
this.mFragment = fragment;
}
}
ArrayList<Op> mOps = new ArrayList<>();
void addOp(Op op) {
mOps.add(op);
op.mEnterAnim = mEnterAnim;
op.mExitAnim = mExitAnim;
op.mPopEnterAnim = mPopEnterAnim;
op.mPopExitAnim = mPopExitAnim;
}
/**
* Calls {@link #add(int, Fragment, String)} with a 0 containerViewId.
*/
@NonNull
public FragmentTransaction add(@NonNull Fragment fragment, @Nullable String tag) {
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
@NonNull
public FragmentTransaction remove(@NonNull Fragment fragment) {
addOp(new Op(OP_REMOVE, fragment));
return this;
}
}
當(dāng)執(zhí)行FragmentTransaction.commit時(shí),最終會(huì)調(diào)用FragmentManager.enqueueAction(),將BackStackRecord加入到FragmentManager的一個(gè)執(zhí)行隊(duì)列中,這個(gè)操作隊(duì)列會(huì)在主線程中順序被執(zhí)行鬼譬。
final class BackStackRecord{
@Override
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(TAG);
PrintWriter pw = new PrintWriter(logw);
dump(" ", pw);
pw.close();
}
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
}
二娜膘、BackStackRecord的執(zhí)行
BackStackRecord加入到FragmentManager隊(duì)列中是如何被執(zhí)行的,Fragment又是如何顯示出來的呢?(add操作)
FragmentManagerImpl類
/**
* Adds an action to the queue of pending actions.
*
* @param action the action to add
* @param allowStateLoss whether to allow loss of state information
* @throws IllegalStateException if the activity has been destroyed
*/
public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mDestroyed || mHost == null) {
if (allowStateLoss) {
// This FragmentManager isn't attached, so drop the entire transaction.
return;
}
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList<>();
}
mPendingActions.add(action);
scheduleCommit();
}
}
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();
}
}
}
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
/**
* Only call from main thread!
*/
public boolean execPendingActions() {
ensureExecReady(true);
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
return didSomething;
}
private void removeRedundantOperationsAndExecute(ArrayList<BackStackRecord> records,ArrayList<Boolean> isRecordPop) {
executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
}
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();
}
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) {
//注釋一:將ops操作 拆解為基本操作的序列
oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
} else {
oldPrimaryNav = record.trackAddedFragmentsInPop(mTmpAddedFragments, oldPrimaryNav);
}
addToBackStack = addToBackStack || record.mAddToBackStack;
}
mTmpAddedFragments.clear();
executeOps(records, isRecordPop, startIndex, endIndex);
}
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);
final boolean isPop = isRecordPop.get(i);
if (isPop) {
record.bumpBackStackNesting(-1);
boolean moveToState = i == (endIndex - 1);
//注釋二:出棧操作,執(zhí)行executePopOps
record.executePopOps(moveToState);
} else {
record.bumpBackStackNesting(1);
//注釋三:入棧操作,執(zhí)行executeOps()
record.executeOps();
}
}
}
- 注釋一:record.expandOps()會(huì)將ops操作 拆解為更簡單的基本操作序列,如replace()操作,會(huì)被拆解為N個(gè)Remove+1個(gè)Add操作优质,保存在mOps數(shù)組中竣贪。
- 注釋二:如果當(dāng)前BackStackRecord是出棧操作,則執(zhí)行record.executePopOps()
- 注釋三:如果當(dāng)前BackStackRecord是入棧操作,則執(zhí)行record.executeOps()
下面我們重點(diǎn)看一下BackStackRecord的這三個(gè)方法
2.1、 BackStackRecord.expandOps():
expandOps的主要作用擴(kuò)展Op操作,將原始是Ops操作擴(kuò)展成更基本的Ops序列,它會(huì)修改FragmentManagetImpl的mAdded數(shù)組和oldPrimaryNav
/**
* Expands all meta-ops into their more primitive equivalents. This must be called prior to
* {@link #executeOps()} or any other call that operations on mOps for forward navigation.
* It should not be called for pop/reverse navigation operations.
*
* <p>Removes all OP_REPLACE ops and replaces them with the proper add and remove
* operations that are equivalent to the replace.</p>
*
* <p>Adds OP_UNSET_PRIMARY_NAV ops to match OP_SET_PRIMARY_NAV, OP_REMOVE and OP_DETACH
* ops so that we can restore the old primary nav fragment later. Since callers call this
* method in a loop before running ops from several transactions at once, the caller should
* pass the return value from this method as the oldPrimaryNav parameter for the next call.
* The first call in such a loop should pass the value of
* {@link FragmentManager#getPrimaryNavigationFragment()}.</p>
*
* @param added Initialized to the fragments that are in the mManager.mAdded, this
* will be modified to contain the fragments that will be in mAdded
* after the execution ({@link #executeOps()}.
* @param oldPrimaryNav The tracked primary navigation fragment as of the beginning of
* this set of ops
* @return the new oldPrimaryNav fragment after this record's ops would be run
*/
@SuppressWarnings("ReferenceEquality")
Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
for (int opNum = 0; opNum < mOps.size(); opNum++) {
final Op op = mOps.get(opNum);
switch (op.mCmd) {
case OP_ADD:
case OP_ATTACH:
//(1)ADD和ATTACH方法,僅將mFragment添加到mAdded數(shù)組
added.add(op.mFragment);
break;
case OP_REMOVE:
case OP_DETACH: {
//(2)REMOVE和DETACH操作,將mFragment從added數(shù)組移除,并插入OP_UNSET_PRIMARY_NAV操作,將oldPrimaryNav移除
added.remove(op.mFragment);
if (op.mFragment == oldPrimaryNav) {
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.mFragment));
opNum++;
oldPrimaryNav = null;
}
}
break;
case OP_REPLACE: {
//(3)REPLACE 將added數(shù)組中,所有mContainerId匹配的Frament移除,然后再j將當(dāng)前Frament添加巩螃。replace操作 轉(zhuǎn)變成了REMOVE*N+ADD的序列
final Fragment f = op.mFragment;
final int containerId = f.mContainerId;
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) {
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;
}
final Op removeOp = new Op(OP_REMOVE, old);
removeOp.mEnterAnim = op.mEnterAnim;
removeOp.mPopEnterAnim = op.mPopEnterAnim;
removeOp.mExitAnim = op.mExitAnim;
removeOp.mPopExitAnim = op.mPopExitAnim;
mOps.add(opNum, removeOp);
added.remove(old);
opNum++;
}
}
}
if (alreadyAdded) {
mOps.remove(opNum);
opNum--;
} else {
op.mCmd = OP_ADD;
added.add(f);
}
}
break;
//(4)SET_PRIMARY_NAV 操作,更新oldPrimaryNav的值
case OP_SET_PRIMARY_NAV: {
// It's ok if this is null, that means we will restore to no active
// primary navigation fragment on a pop.
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, oldPrimaryNav));
opNum++;
// Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
oldPrimaryNav = op.mFragment;
}
break;
}
}
return oldPrimaryNav;
}
- (1)ADD和ATTACH方法,僅將mFragment添加到mAdded數(shù)組
- (2)REMOVE和DETACH操作,將mFragment從added數(shù)組移除,并插入OP_UNSET_PRIMARY_NAV操作,將oldPrimaryNav移除演怎。
- (3)REPLACE 將added數(shù)組中,所有mContainerId匹配的Frament移除,然后再j將當(dāng)前Frament添加。replace操作 轉(zhuǎn)變成了REMOVE*N+ADD的序列避乏。
- (4)SET_PRIMARY_NAV 操作,更新oldPrimaryNav的值
2.2爷耀、 BackStackRecord.executeOps() 入棧操作
當(dāng)Fragment入棧時(shí),會(huì)執(zhí)行BackStackRecord.executeOps()方法
executeOps方法中,將Op操作 都代理到了FragmentManagerImpl對應(yīng)的方法。
void executeOps() {
final int numOps = mOps.size();
for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = mOps.get(opNum);
final Fragment f = op.mFragment;
if (f != null) {
f.setNextTransition(mTransition, mTransitionStyle);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mEnterAnim);
mManager.addFragment(f, false);
break;
case OP_REMOVE:
f.setNextAnim(op.mExitAnim);
mManager.removeFragment(f);
break;
case OP_HIDE:
f.setNextAnim(op.mExitAnim);
mManager.hideFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.mEnterAnim);
mManager.showFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mExitAnim);
mManager.detachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mEnterAnim);
mManager.attachFragment(f);
break;
case OP_SET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(f);
break;
case OP_UNSET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(null);
break;
case OP_SET_MAX_LIFECYCLE:
mManager.setMaxLifecycle(f, op.mCurrentMaxState);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
}
if (!mReorderingAllowed && op.mCmd != OP_ADD && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed) {
// Added fragments are added at the end to comply with prior behavior.
mManager.moveToState(mManager.mCurState, true);
}
}
執(zhí)行OP_ADD時(shí) 會(huì)順序執(zhí)行
- FragmentManagerImpl.addFragment()
- FragmentManagerImpl.moveToState()
- FragmentManagerImpl.moveFragmentToExpectedState()
- FragmentManagerImpl.moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive)
addFragment中的核心操作 就是將將Fragmet加入到mAdded數(shù)組,同時(shí)修改Fragment對應(yīng)的標(biāo)志位
public void addFragment(Fragment fragment, boolean moveToStateNow) {
if (DEBUG) Log.v(TAG, "add: " + fragment);
makeActive(fragment);
if (!fragment.mDetached) {
//將Fragmet加入到mAdded數(shù)組
synchronized (mAdded) {
mAdded.add(fragment);
}
//修改frament中的標(biāo)志位
fragment.mAdded = true;
fragment.mRemoving = false;
if (moveToStateNow) {
moveToState(fragment);
}
}
}
操作二:調(diào)用moveToState()方法
moveFragmentToExpectedState->moveToState()
2.3拍皮、 FragmentManagerImpl.moveToState() 執(zhí)行Fragment的狀態(tài)切換
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
// Fragments that are not currently added will sit in the onCreate() state.
if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
newState = Fragment.CREATED;
}
// Don't allow the Fragment to go above its max lifecycle state
// Ensure that Fragments are capped at CREATED instead of ACTIVITY_CREATED.
if (f.mMaxState == Lifecycle.State.CREATED) {
newState = Math.min(newState, Fragment.CREATED);
} else {
newState = Math.min(newState, f.mMaxState.ordinal());
}
//如果newState > Fragment當(dāng)前的狀態(tài)
if (f.mState <= newState) {
switch (f.mState) {
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mHost.mFragmentManager;
//(1)執(zhí)行Fragment.attach()
f.performAttach();
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
} else {
f.mParentFragment.onAttachFragment(f);
}
//(2)執(zhí)行Fragmet.onCreate()
if (!f.mIsCreated) {
dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
f.performCreate(f.mSavedFragmentState);
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = Fragment.CREATED;
}
}
// fall through
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
//(1)提取Fragment的ContainerId 對應(yīng)的ViewGroup
container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
// (2) 調(diào)用Fragment的onCreateView()繪制Fragment中的View
f.mContainer = container;
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
f.mView.setSaveFromParentEnabled(false);
//(3)將Framgnet中的View 添加到ContrainerView當(dāng)中
if (container != null) {
container.addView(f.mView);
}
if (f.mHidden) {
f.mView.setVisibility(View.GONE);
}
//(4)調(diào)用Fragment的OnViewCreated()
f.onViewCreated(f.mView, f.mSavedFragmentState);
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
false);
f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
&& f.mContainer != null;
} else {
f.mInnerView = null;
}
}
//(5)調(diào)用Fragment的onActivityCreated()
f.performActivityCreated(f.mSavedFragmentState);
dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
// fall through
case Fragment.ACTIVITY_CREATED:
//(1) 調(diào)用Fragment.onStart()
if (newState > Fragment.ACTIVITY_CREATED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.performStart();
dispatchOnFragmentStarted(f, false);
}
// fall through
case Fragment.STARTED:
//(1) 調(diào)用Fragment.onResume()
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
f.performResume();
dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
} else if (f.mState > newState) {
... //執(zhí)行一些列反向的操作
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
f.performPause();
dispatchOnFragmentPaused(f, false);
}
// fall through
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.performStop();
dispatchOnFragmentStopped(f, false);
}
// fall through
}
}
if (f.mState != newState) {
f.mState = newState;
}
}
Fragment 有以下幾個(gè)狀態(tài):
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // Fully created, not started.
static final int STARTED = 3; // Created and started, not resumed.
static final int RESUMED = 4; // Created started and resumed.
moveToState()方法 將Fragment由當(dāng)前的mState狀態(tài)切換為newState狀態(tài)歹叮。
當(dāng)newState>Fragment.mState 進(jìn)行Fraggment的正向生命周期,當(dāng)newState<Fragment.state,執(zhí)行Fragment的逆向生命周期。
以正向聲明周期為例,
- Fragment.state == INITIALIZING: 表示Not yet created, 執(zhí)行操作
Fragment.onCreate()
Fragment.onAttach()
- Fragment.state == CREATED: 表示 Created,執(zhí)行操作
(1) 提取Fragment的ContainerId 對應(yīng)的ViewGroup
(2) 調(diào)用Fragment的onCreateView()獲取Fragment中的的View
(3) 將Framgnet中的View 添加到ContrainerView當(dāng)中
(4) 調(diào)用Fragment的OnViewCreated()
(5) 調(diào)用Fragment的onActivityCreated()
- Fragment.state == ACTIVITY_CREATED:表示Fully created, not started铆帽,執(zhí)行操作
Fragment.onStart()
- Fragment.state == STARTED ,表示 Created started and resumed.
2.4咆耿、BackStackRecord.executePopOps()
executePopOps()是Fragment出棧時(shí)的操作,是入棧操作的逆操作。
void executePopOps(boolean moveToState) {
for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
final Op op = mOps.get(opNum);
Fragment f = op.mFragment;
if (f != null) {
f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition),
mTransitionStyle);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mPopExitAnim);
mManager.removeFragment(f);
break;
case OP_REMOVE:
f.setNextAnim(op.mPopEnterAnim);
mManager.addFragment(f, false);
break;
case OP_HIDE:
f.setNextAnim(op.mPopEnterAnim);
mManager.showFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.mPopExitAnim);
mManager.hideFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mPopEnterAnim);
mManager.attachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mPopExitAnim);
mManager.detachFragment(f);
break;
case OP_SET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(null);
break;
case OP_UNSET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(f);
break;
case OP_SET_MAX_LIFECYCLE:
mManager.setMaxLifecycle(f, op.mOldMaxState);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
}
if (!mReorderingAllowed && op.mCmd != OP_REMOVE && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed && moveToState) {
mManager.moveToState(mManager.mCurState, true);
}
}
2.5爹橱、總結(jié)一下執(zhí)行replace()時(shí) Fragment的View是如何顯示出來的
假設(shè)Actvity中當(dāng)前正在顯示FragmentA,此時(shí)在同一個(gè)ContainerID上執(zhí)行replace(FragmentB())萨螺。執(zhí)行過程如下:
- BackStackRecord.expendOp()方法將OP_REPLACE 操作被拆分 一個(gè)OP_REMOVE和一個(gè)OP_ADD操作
- 執(zhí)行 BackStackRecord.executeOps()
- FragmentA執(zhí)行OP_REMOVE 被移除
- FragmentB執(zhí)行OP_ADD 被添加
- FragmentManagerImpl.moveToState()
當(dāng)Fragment.mState == CREATED 時(shí),執(zhí)行一下操作
(1) 提取Fragment的ContainerId 對應(yīng)的ViewGroup
(2) 調(diào)用Fragment的onCreateView()獲取Fragment中的的View
(3) 將Framgnet中的View 添加到ContrainerView當(dāng)中
(4) 調(diào)用Fragment的OnViewCreated()
(5) 調(diào)用Fragment的onActivityCreated()
至此FragmentB 被添加到Activity的View樹中,顯示出來。
三愧驱、Fragment是如何回退的慰技。
FragmentManager中有一個(gè)mBackStack數(shù)組,承載了加入回退棧中的FragmentTransaction操作
final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2
ArrayList<BackStackRecord> mBackStack;//這個(gè)就是保存調(diào)用了addToBackStack方法的FragementTransaction,你看就是這個(gè)東西記錄了,你commit的操作 所以當(dāng)你調(diào)用了addToBackStack 以后再按返回鍵 就可以回到上一個(gè)fragment了
}
調(diào)用FragmentTransaction.addToBackStack()组砚,便將自己加入到回退棧中吻商。
@NonNull
public FragmentTransaction addToBackStack(@Nullable 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;
}
當(dāng)點(diǎn)擊Android的回退鍵時(shí),會(huì)調(diào)用Activity的onBackPressed()方法。最終調(diào)用fragmentManager.popBackStackImmediate()方法糟红。
public void onBackPressed() {
if (mActionBar != null && mActionBar.collapseActionView()) {
return;
}
FragmentManager fragmentManager = mFragments.getFragmentManager();
if (fragmentManager.isStateSaved() || !fragmentManager.popBackStackImmediate()) {
finishAfterTransition();
}
}
private boolean popBackStackImmediate(String name, int id, int flags) {
//(1)popBackStackState 負(fù)責(zé)遍歷mBackStack回退棧,將回退棧中的操作整理填充到this.mTmpRecords,并記錄是否是pop回退操作(保留在this.mTmpIsPop)中
boolean executePop = this.popBackStackState(this.mTmpRecords, this.mTmpIsPop, name, id, flags);
if (executePop) {
this.mExecutingActions = true;
try {
//(2) 根據(jù)this.mTmpRecords和this.mTmpIsPop 執(zhí)行具體的transantion
this.removeRedundantOperationsAndExecute(this.mTmpRecords, this.mTmpIsPop);
} finally {
this.cleanupExec();
}
}
this.doPendingDeferredStart();
this.burpActive();
return executePop;
}
最終會(huì)調(diào)用到executeOps()方法手报,因?yàn)槭腔赝瞬僮?isRecordPop == true,會(huì)執(zhí)行record.executePopOps(moveToState);
private static void executeOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
for(int i = startIndex; i < endIndex; ++i) {
BackStackRecord record = (BackStackRecord)records.get(i);
boolean isPop = (Boolean)isRecordPop.get(i);
if (isPop) {
record.bumpBackStackNesting(-1);
boolean moveToState = i == endIndex - 1;
record.executePopOps(moveToState);
} else {
record.bumpBackStackNesting(1);
record.executeOps();
}
}
}
executePopOps()執(zhí)行原transaction操作的反向操作,如原操作是OP_ADD操作,則實(shí)際執(zhí)行OP_REMOVE操作;操作是OP_REMOVE操作蚯舱,則執(zhí)行OP_ADD操作。
void executePopOps(boolean moveToState) {
for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
final Op op = mOps.get(opNum);
Fragment f = op.mFragment;
if (f != null) {
f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition),
mTransitionStyle);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mPopExitAnim);
mManager.removeFragment(f);
break;
case OP_REMOVE:
f.setNextAnim(op.mPopEnterAnim);
mManager.addFragment(f, false);
break;
case OP_HIDE:
f.setNextAnim(op.mPopEnterAnim);
mManager.showFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.mPopExitAnim);
mManager.hideFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mPopEnterAnim);
mManager.attachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mPopExitAnim);
mManager.detachFragment(f);
break;
case OP_SET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(null);
break;
case OP_UNSET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(f);
break;
case OP_SET_MAX_LIFECYCLE:
mManager.setMaxLifecycle(f, op.mOldMaxState);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
}
if (!mReorderingAllowed && op.mCmd != OP_REMOVE && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed && moveToState) {
mManager.moveToState(mManager.mCurState, true);
}
}
注意:FragmenetTransantion.replace()操作,執(zhí)行時(shí)會(huì)被拆分成remove+add操作;相應(yīng)的,回退時(shí),順序執(zhí)行執(zhí)行remove和add操作掩蛤。
四枉昏、參考文章:
http://www.reibang.com/p/1ee67d935757
https://www.cnblogs.com/punkisnotdead/p/4974527.html