關於作者
郭孝星,程式設計師,吉他手,主要從事Android平臺基礎架構方面的工作,歡迎交流技術方面的問題,可以去我的Github提issue或者發郵件至guoxiaoxingse@163.com與我交流。
文章目錄
- 一 Fragment管理流程
- 二 Fragment生命週期
- 三 Fragment回退棧
A Fragment is a piece of an application's user interface or behavior that can be placed in an Activity.
Fragment放置在Activity容器中,通常用來作為UI的片段,在日常的開發中也有著廣泛的應用,先來看一段常用的程式碼。
DemoFragment demoFragment = DemoFragment.newInstance("param1", "param2");
Bundle bundle = new Bundle();
demoFragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, demoFragment)
.commit();複製程式碼
這是我們非常常見的程式碼,藉著這段程式碼,引出我們今天的主題:針對Fragment的全面的原始碼分析。
一 Fragment操作方法
Fragment的操作是一種事務操作,什麼是事務??簡單來說就是一個原子操作,要麼被成功執行,否則原來的操作會回滾,各個操作彼此之間互不干擾。我們先整體看下Fragment的操作
序列圖。
嗯,看起來有點長?,不要方,我們先來看看這裡面頻繁出現的幾個類的作用。
- FragmentActivity:這個自不必說,它是Fragment的容器Activity,只有你的Activity繼承自FragmentActivity,你才能使用Fragment,Android的AppCompatActivity就繼承自FragmentActivity。
- FragmentManager:Fragment的管理是由FragmentManager這個類的完成的,我們通常在Activity中使用getSupportFragmentManager()方法來獲取。它是一個抽象類,其實現類是FragmentManagerImpl。
- FragmentTransaction:定義了Fragment的所有操作,我們通常通過getSupportFragmentManager().beginTransaction()方法來獲取。它是一個抽象類,其實現類是BackStackRecord,BackStackRecord將Fragment、入棧資訊、轉場動畫、相應的
操作等資訊包裝起來,傳遞給FragmentManager呼叫。 - FragmentHostCallback:抽象類,它將Fragment、Activity與FragmentManager串聯成一個整體,FragmentActivity的內部類HostCallbacks繼承了這個抽象類。
- FragmentController:它的主要職責是控制Fragment的生命週期,它在FragmentActivity裡以HostCallbacks為引數被建立,持有HostCallbacks的引用。
1.1 操作的封裝
Fragment的操作方法一共有七種:
- add
- replace
- remove
- hide
- show
- detach
- attach
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
@Override
public FragmentTransaction add(Fragment fragment, String tag) {
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
@Override
public FragmentTransaction add(int containerViewId, Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}
@Override
public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
doAddOp(containerViewId, fragment, tag, OP_ADD);
return this;
}
@Override
public FragmentTransaction replace(int containerViewId, Fragment fragment) {
return replace(containerViewId, fragment, null);
}
@Override
public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
if (containerViewId == 0) {
throw new IllegalArgumentException("Must use non-zero containerViewId");
}
doAddOp(containerViewId, fragment, tag, OP_REPLACE);
return this;
}
@Override
public FragmentTransaction remove(Fragment fragment) {
Op op = new Op();
op.cmd = OP_REMOVE;
op.fragment = fragment;
addOp(op);
return this;
}
@Override
public FragmentTransaction hide(Fragment fragment) {
Op op = new Op();
op.cmd = OP_HIDE;
op.fragment = fragment;
addOp(op);
return this;
}
@Override
public FragmentTransaction show(Fragment fragment) {
Op op = new Op();
op.cmd = OP_SHOW;
op.fragment = fragment;
addOp(op);
return this;
}
@Override
public FragmentTransaction detach(Fragment fragment) {
Op op = new Op();
op.cmd = OP_DETACH;
op.fragment = fragment;
addOp(op);
return this;
}
@Override
public FragmentTransaction attach(Fragment fragment) {
Op op = new Op();
op.cmd = OP_ATTACH;
op.fragment = fragment;
addOp(op);
return this;
}
}複製程式碼
你可以發現,這些方法最終都呼叫了addOp()方法,Op是什麼??Op封裝了操作命令、Fragment、動畫等內容。上面我們說過BackStackRecord將Fragment與相應應的操作包裝起來,傳遞給FragmentManager呼叫。
static final class Op {
int cmd;
Fragment fragment;
int enterAnim;
int exitAnim;
int popEnterAnim;
int popExitAnim;
}複製程式碼
cmd對應了響應的操作。
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;複製程式碼
我們來看看addOp()方法的實現。
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
ArrayList<Op> mOps = new ArrayList<>();
void addOp(Op op) {
mOps.add(op);
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
}
}複製程式碼
上面程式碼的最後一步是commit()方法,該方法提交事務操作,我們來看看它的實現。
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
@Override
public int commit() {
return commitInternal(false);
}
//allowStateLoss是個標誌位,表示是否允許狀態丟失
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);
pw.close();
}
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
}複製程式碼
可以看到BackStackRecord完成了對Fragment操作的封裝,並比較給FragmentManager呼叫。
1.2 操作的呼叫
從上面的序列圖我們可以看出,在commit()方法執行後,會呼叫FragmentManager.enqueueAction()方法,並通過handler.post()切換到主執行緒去執行這個Action,執行時間未知。
這個handler正是FragmentActivity裡建立的Handler。
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
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;
f.setNextTransition(mTransition, mTransitionStyle);
//Fragment操作
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;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
}
if (!mAllowOptimization && op.cmd != OP_ADD) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mAllowOptimization) {
// Added fragments are added at the end to comply with prior behavior.
mManager.moveToState(mManager.mCurState, true);
}
}
}複製程式碼
因而,Fragment的操作:
- add
- remove
- replace
- hide
- show
- detach
- attach
都轉換成了FragmentManager的方法:
- addFragment
- removeFragment
- removeFragment + addFragment
- hideFragment
- showFragment
- detachFragment
- attachFragment
並呼叫FragmentManager.moveToState()方法做Fragment的狀態遷移。上述的這幾種Fragment的操作方法都做了哪些事情呢??
- 將Fragment從mAdded列表中新增或移除。
- 改變Fragment的mAdded、mRemoving、mHidden等標誌位
要理解以下方法,我們要先看看Fragment裡的幾個標誌位的含義。
- boolean mAdded:表示Fragment是否被新增到FragmentManager裡的Fragment列表mAdded中。
- boolean mRemoving:表示Fragment是否從Activity中移除。
- boolean mHidden:表示Fragment是否對使用者隱藏。
- boolean mDetached:表示Fragment是否已經從宿主Activity中分離。
final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
//新增Fragment
public void addFragment(Fragment fragment, boolean moveToStateNow) {
if (mAdded == null) {
mAdded = new ArrayList<Fragment>();
}
if (DEBUG) Log.v(TAG, "add: " + fragment);
makeActive(fragment);
if (!fragment.mDetached) {
if (mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: " + fragment);
}
synchronized (mAdded) {
mAdded.add(fragment);
}
fragment.mAdded = true;
fragment.mRemoving = false;
if (fragment.mView == null) {
fragment.mHiddenChanged = false;
}
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
}
if (moveToStateNow) {
moveToState(fragment);
}
}
}
//移除Fragment
public void removeFragment(Fragment fragment) {
if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting);
final boolean inactive = !fragment.isInBackStack();
if (!fragment.mDetached || inactive) {
if (mAdded != null) {
synchronized (mAdded) {
mAdded.remove(fragment);
}
}
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
}
fragment.mAdded = false;
fragment.mRemoving = true;
}
}
//隱藏Fragment:將一個Fragment標記成將要隱藏狀態,顯示工作有completeShowHideFragment(}方法完成
public void hideFragment(Fragment fragment) {
if (DEBUG) Log.v(TAG, "hide: " + fragment);
if (!fragment.mHidden) {
fragment.mHidden = true;
// Toggle hidden changed so that if a fragment goes through show/hide/show
// it doesn't go through the animation.
fragment.mHiddenChanged = !fragment.mHiddenChanged;
}
}
//顯示Fragment:將一個Fragment標記成將要顯示狀態,顯示工作有completeShowHideFragment(}方法完成
public void showFragment(Fragment fragment) {
if (DEBUG) Log.v(TAG, "show: " + fragment);
if (fragment.mHidden) {
fragment.mHidden = false;
// Toggle hidden changed so that if a fragment goes through show/hide/show
// it doesn't go through the animation.
fragment.mHiddenChanged = !fragment.mHiddenChanged;
}
}
//將Fragment從宿主Activity分離
public void detachFragment(Fragment fragment) {
if (DEBUG) Log.v(TAG, "detach: " + fragment);
if (!fragment.mDetached) {
fragment.mDetached = true;
if (fragment.mAdded) {
// We are not already in back stack, so need to remove the fragment.
if (mAdded != null) {
if (DEBUG) Log.v(TAG, "remove from detach: " + fragment);
synchronized (mAdded) {
mAdded.remove(fragment);
}
}
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
}
fragment.mAdded = false;
}
}
}
//將Fragment關聯3到宿主Activity
public void attachFragment(Fragment fragment) {
if (DEBUG) Log.v(TAG, "attach: " + fragment);
if (fragment.mDetached) {
fragment.mDetached = false;
if (!fragment.mAdded) {
if (mAdded == null) {
mAdded = new ArrayList<Fragment>();
}
if (mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: " + fragment);
}
if (DEBUG) Log.v(TAG, "add from attach: " + fragment);
synchronized (mAdded) {
mAdded.add(fragment);
}
fragment.mAdded = true;
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
}
}
}
}
}複製程式碼
可以看到這些方法大體類似,差別在於它們處理的標誌位不同,這也導致了後續的moveToState()在處理它們的時候回區別對待,具體說來:
- add操作新增一個Fragment,會依次呼叫 onAttach, onCreate, onCreateView, onStart and onResume 等方法。
- attach操作關聯一個Fragment,會依次呼叫onCreateView, onStart and onResume 。
- remove操作移除一個Fragment,會依次呼叫nPause, onStop, onDestroyView, onDestroy and onDetach 等方法。
- detach操作分離一個Fragment,會依次呼叫onPause, onStop and onDestroyView 等方法。
detach後的Fragment可以再attach,而remove後的Fragment卻不可以,只能重新add。
理解完了Fragment的操作,我們再來看看它的生命週期的變化,這也是我們的重點。
Fragment生命週期
我們先來看一張完整的Fragment生命週期圖。
我們都知道Fragment的生命週期依賴於它的宿主Activity,但事實的情況卻並不這麼簡單。
- onAttach:當Fragment與宿主Activity建立聯絡的時候呼叫。
- onCreate:用來完成Fragment的初始化建立工作。
- onCreateView:建立並返回View給Fragment。
- onActivityCreated:通知Fragment當前Activity的onCreate()方法已經呼叫完成。
- onViewStateRestored:通知Fragment以前儲存的View狀態都已經被恢復。
- onStart:Fragment已經對使用者可見時呼叫,當然這個基於它的宿主Activity的onStart()方法已經被呼叫。
- onResume:Fragment已經開始和使用者互動時呼叫,當然這個基於它的宿主Activity的onResume()方法已經被呼叫。
- onPause:Fragment不再和使用者互動時呼叫,這通常發生在宿主Activity的onPause()方法被呼叫或者Fragment被修改(replace、remove)。
- onStop:Fragment不再對使用者可見時呼叫,這通常發生在宿主Activity的onStop()方法被呼叫或者Fragment被修改(replace、remove)。
- onDestroyView:Fragment釋放View資源時呼叫。
- onDetach:Fragment與宿主Activity脫離聯絡時呼叫。
在FragmentManager中,完成Fragment狀態變換的主要有四個方法:
moveToState(Fragment f)
moveToState(int newState, boolean always)
moveFragmentToExpectedState(Fragment f)
moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive)
它們的觸發流程也很簡單,比方說FragmentActivity觸發了onResume()方法。
public class FragmentActivity extends BaseFragmentActivityJB implements
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompatApi23.RequestPermissionsRequestCodeValidator {
@Override
protected void onDestroy() {
super.onDestroy();
doReallyStop(false);
mFragments.dispatchDestroy();
mFragments.doLoaderDestroy();
}
}複製程式碼
它會去呼叫Fragment的dispatchDestory()方法,Fragment又接著會去呼叫FragmentManager的dispatchDestory()方法。
final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
public void dispatchDestroy() {
mDestroyed = true;
execPendingActions();
mExecutingActions = true;
moveToState(Fragment.INITIALIZING, false);
mExecutingActions = false;
mHost = null;
mContainer = null;
mParent = null;
}
}複製程式碼
最終這些處理都會迴歸到上面這四個方法中來,而這四個方法最終發揮作用當然是最後一個引數最多的方法,其他的方法都只是做了引數的處理和情況的判斷。
Fragment定義了六種狀態
static final int INITIALIZING = 0; // 未建立
static final int CREATED = 1; // 已建立
static final int ACTIVITY_CREATED = 2; // 宿主Activity已經結束建立
static final int STOPPED = 3; // Fragment的onCreate()方法已完成,onStart()即將開始
static final int STARTED = 4; // Fragment的onCreate()和onStart()方法都已完成,onResume()即將開始
static final int RESUMED = 5; // Fragment的onCreate()、onStart()和onResume()方法都已完成複製程式碼
final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
//狀態判斷
...
//當前狀態大於新狀態,從上面的狀態表可以看出,狀態值越小
//就說明處於越早的階段,一般對應add等操作
if (f.mState < newState) {
...
switch (f.mState) {
//未建立
case Fragment.INITIALIZING:
...
f.onAttach(mHost.getContext());
...
//Fragment被定義在佈局檔案裡的情形,需要先從佈局檔案裡inflate出view
if (f.mFromLayout) {
f.mView = f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
if (f.mView != null) {
...
f.onViewCreated(f.mView, f.mSavedFragmentState);
} else {
f.mInnerView = null;
}
}
//已建立
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
if (!f.mFromLayout) {
...
if (f.mView != null) {
...
f.onViewCreated(f.mView, f.mSavedFragmentState);
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
false);
...
} else {
f.mInnerView = null;
}
}
...
f.performActivityCreated(f.mSavedFragmentState);
...
}
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
f.mState = Fragment.STOPPED;
}
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.performStart();
dispatchOnFragmentStarted(f, false);
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
f.performResume();
dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
}
//當前狀態大於新狀態,一般對應remove等操作
else if (f.mState > newState) {
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
f.performPause();
dispatchOnFragmentPaused(f, false);
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.performStop();
dispatchOnFragmentStopped(f, false);
}
case Fragment.STOPPED:
if (newState < Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
f.performReallyStop();
}
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
...
f.performDestroyView();
dispatchOnFragmentViewDestroyed(f, false);
...
}
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
...
if (f.getAnimatingAway() != null) {
f.setStateAfterAnimating(newState);
newState = Fragment.CREATED;
} else {
....
if (!f.mRetaining) {
f.performDestroy();
dispatchOnFragmentDestroyed(f, false);
} else {
f.mState = Fragment.INITIALIZING;
}
f.performDetach();
dispatchOnFragmentDetached(f, false);
...
}
}
}
}
...
}
}複製程式碼
可以發現進入該方法後會先將Fragment的當前狀態與新狀態進行比較:
- 如果f.mState < newState,則說明Fragment狀態會從按照INITIALIZING、CREATED、ACTIVITY_CREATED、STOPPED、STARTED、RESUMED的狀態進行變化,switch語句沒有break,會一直順序
執行,通知Fragment進入相應的狀態,並回撥Fragment裡相應的生命週期方法。 - 如果f.mState < newState,則剛好和上面是反過來的過程。
這樣便完成了Fragment狀態的遷移和生命週期方法的回撥。
三 Fragment回退棧
什麼是Fragment回退棧呢??
這個很好理解,和Activity棧相似,放在Activity裡的Fragment,如果不做額外處理的話,在點選返回的時候,會直接finish當前Activity,Fragment回退棧就是用來處理Fragment返回的問題。
Fragment的回退棧也是由Fragment來管理的,關於FragmentManger的獲取,一是FragmentActivity裡的getSupportFragmentManager(),二是Fragment裡的getChildFragmentManager(),它們
返回的都是FragmentManagerImpl物件,對Fragment的棧進行管理。
我們先來看看常用的棧操作方法。
入棧
入棧操作通過etSupportFragmentManager.beiginTransaction().addToBackStack()方法完成,它的具體實現在BackRecordStack裡。
addToBackStack(String name):入棧,這個方法的實現很簡單,就是將BackRecordStack的成員變數mName賦值,mAddToBackStack置true,表示自己要新增進回退棧, 這樣在呼叫commit()方法提交操作時,FragmentManager
會為該Fragment分配棧索引,並將它新增進回退棧列表,供後續出棧的時候呼叫。
出棧
出棧操作是通過getSupportFragmentManager.popBackStack()等方法完成的,它的具體實現在FragmentManagerImpl裡。
- popBackStack():棧頂Fragment出棧操作,這是一個非同步方法,放在訊息佇列中等待執行。
- popBackStackImmediate():棧頂Fragment出棧操作,這是一個同步方法,會被立即執行。
- popBackStack(String name, int flags):和popBackStack()方法相似,不過指定了出棧的Fragment的name,該name以上的Fragment全部出棧,flags(POP_BACK_STACK_INCLUSIVE)用來
控制出棧的包不包括它自己。 - popBackStackImmediate(String name, int flags):和popBackStackImmediate()方法相似,不過指定了出棧的Fragment的name,該name以上的Fragment全部出棧,flags(POP_BACK_STACK_INCLUSIVE)用來
控制出棧的包不包括它自己。 - popBackStack(String id, int flags):和popBackStack()方法相似,不過指定了出棧的Fragment的id,該id以上的Fragment全部出棧,flags(POP_BACK_STACK_INCLUSIVE)用來
控制出棧的包不包括它自己。 - popBackStackImmediate(String id, int flags):和popBackStackImmediate()方法相似,不過指定了出棧的Fragment的id,該id以上的Fragment全部出棧,flags(POP_BACK_STACK_INCLUSIVE)用來
控制出棧的包不包括它自己。 - getBackStackEntryCount():返回棧中Fragment的個數。
- getBackStackEntryAt(int index):返回指定位置的Fragment。
我們再來看看這些方法的實現。
final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
@Override
public void popBackStack() {
enqueueAction(new PopBackStackState(null, -1, 0), false);
}
@Override
public boolean popBackStackImmediate() {
checkStateLoss();
return popBackStackImmediate(null, -1, 0);
}
}複製程式碼
PopBackStackState實現了OpGenerator介面,封裝了將要出棧的Fragment的資訊,包括mName、mId與mFlags資訊。如果你有細心看,上面我們提到的FragmentTransaction的實現類BackStackRecord
也實現了這個介面。
private class PopBackStackState implements OpGenerator {
final String mName;
final int mId;
final int mFlags;
PopBackStackState(String name, int id, int flags) {
mName = name;
mId = id;
mFlags = flags;
}
@Override
public boolean generateOps(ArrayList<BackStackRecord> records,
ArrayList<Boolean> isRecordPop) {
return popBackStackState(records, isRecordPop, mName, mId, mFlags);
}
}複製程式碼
popBackStack()也呼叫了enqueueAction()方法,後續的流程和上面的Fragment操作流程是一樣的,出棧操作最終對應的是Fragment的remove()操作,因此它對Fragment生命週期的影響和remove()操作相同。
至於popBackStackImmediate()的實現,則就是直接呼叫執行操作的方法,少了加入佇列的等待過程,具體流程也和上面的Fragment操作一樣。
final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
private boolean popBackStackImmediate(String name, int id, int flags) {
execPendingActions();
ensureExecReady(true);
boolean executePop = popBackStackState(mTmpRecords, mTmpIsPop, name, id, flags);
if (executePop) {
mExecutingActions = true;
try {
optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
}
doPendingDeferredStart();
burpActive();
return executePop;
}
}複製程式碼