FragmentBackStack分析
日志对应场景1:
启动空白的MainActivity
,并 add 碎片DispatchFragment
。
DispatchFragment
包含一个ViewPager
,且ViewPager
默认加载 3 个ViewPagerChildFragment
。
ViewPagerChildFragment
中仅含有一个TextView
用于指示当前下标。
// >>> MainActivity 附加 DispatchFragment
// Step 1: 这一步的 commit 去哪儿了?
/**
> BackStackRecord实现了 Runnable 接口,以便于 Handler传递消息;
> 当 BackStackRecord(FragmentTransaction)提交执行,并被真正异步执行时触发。
*/
// Step 2: 执行附加
Run: BackStackEntry{2f4c96a #0}
Bump nesting in BackStackEntry{2f4c96a #0} by 1
// DispatchFragment附加次数为1次;
Bump nesting of DispatchFragment{9943e5b id=0x7f0c0050} to 1
add: DispatchFragment{9943e5b id=0x7f0c0050}
Allocated fragment index DispatchFragment{9943e5b #0 id=0x7f0c0050}
// Step 3: 状态管理
moveto CREATED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto ACTIVITY_CREATED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto STARTED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto RESUMED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
// !!! 为什么此处ViewPager不是初始化2个,而是1个呢???;
moveto CREATED: ViewPagerChildFragment{8b95e46 id=0x7f0c0051}
// >>> DispatchFragment 附加 ViewPagerChildFragment
// Step 1: 提交事务
Commit: BackStackEntry{1caa807}
= mName=null mIndex=-1 mCommitted=false
= Operations:
= Op #0: ADD ViewPagerChildFragment{8b95e46 id=0x7f0c0051}
= Op #1: ADD ViewPagerChildFragment{ee5dd34 id=0x7f0c0051}
// Step 2: 执行附加
Run: BackStackEntry{1caa807}
add: ViewPagerChildFragment{8b95e46 id=0x7f0c0051}
Allocated fragment index ViewPagerChildFragment{8b95e46 #0 id=0x7f0c0051}
add: ViewPagerChildFragment{ee5dd34 id=0x7f0c0051}
Allocated fragment index ViewPagerChildFragment{ee5dd34 #1 id=0x7f0c0051}
// Step 3: 状态管理
moveto ACTIVITY_CREATED: ViewPagerChildFragment{8b95e46 #0 id=0x7f0c0051}
moveto STARTED: ViewPagerChildFragment{8b95e46 #0 id=0x7f0c0051}
moveto RESUMED: ViewPagerChildFragment{8b95e46 #0 id=0x7f0c0051}
moveto CREATED: ViewPagerChildFragment{ee5dd34 #1 id=0x7f0c0051}
moveto ACTIVITY_CREATED: ViewPagerChildFragment{ee5dd34 #1 id=0x7f0c0051}
moveto STARTED: ViewPagerChildFragment{ee5dd34 #1 id=0x7f0c0051}
moveto RESUMED: ViewPagerChildFragment{ee5dd34 #1 id=0x7f0c0051}
摘取代码分析1
// FragmentManager.class
void bumpBackStackNesting(int amt) {
if (!mAddToBackStack) {
return;
}
# > 通过 amt{1,-1} 指令,操作内嵌在回退栈的对象(实际为 Op)
# > 1 代表入栈 ; -1 代表出栈;
# > Bump nesting in BackStackEntry{2f4c96a #0} by 1
# > 当前附加中的BackStackEntry要执行的 amt 命令为入栈;
if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting in " + this
+ " by " + amt);
Op op = mHead;
while (op != null) {
if (op.fragment != null) {
op.fragment.mBackStackNesting += amt;
# > 当前附加在 op.fragment 的附加次数;
if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
+ op.fragment + " to " + op.fragment.mBackStackNesting);
}
if (op.removed != null) {
for (int i=op.removed.size()-1; i>=0; i--) {
Fragment r = op.removed.get(i);
r.mBackStackNesting += amt;
# > 当前附加在 op.fragment 的附加次数;
if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
+ r + " to " + r.mBackStackNesting);
}
}
op = op.next;
}
}
日志对应场景2
承接上面的场景,点击ViewPagerChildFragment
跳转到DetailFragment
。
DetailFragment
replace DispatchFragment
所附加的 R.id.xx
。
// Step 1:
Commit: BackStackEntry{50f64d4}
= mName=null mIndex=-1 mCommitted=false
= Operations:
= Op #0: REPLACE DetailFragment{83eb67d id=0x7f0c0050}
Setting back stack index 1 to BackStackEntry{50f64d4}
// Step 2:
=Run: BackStackEntry{50f64d4 #1}
=Bump nesting in BackStackEntry{50f64d4 #1} by 1
=Bump nesting of DetailFragment{83eb67d id=0x7f0c0050} to 1
=OP_REPLACE: adding=DetailFragment{83eb67d id=0x7f0c0050} old=DispatchFragment{9943e5b #0 id=0x7f0c0050}
// !!! 注意 DispatchFragment 此处 nest = 2
=Bump nesting of DispatchFragment{9943e5b #0 id=0x7f0c0050} to 2
// Step 3:
remove: DispatchFragment{9943e5b #0 id=0x7f0c0050} nesting=2
movefrom RESUMED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
movefrom RESUMED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
movefrom RESUMED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
movefrom STARTED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
movefrom STARTED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
movefrom STARTED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
movefrom STOPPED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
movefrom STOPPED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
movefrom STOPPED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
movefrom ACTIVITY_CREATED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
movefrom ACTIVITY_CREATED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
movefrom ACTIVITY_CREATED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
add: DetailFragment{83eb67d id=0x7f0c0050}
Allocated fragment index DetailFragment{83eb67d #1 id=0x7f0c0050}
moveto CREATED: DetailFragment{83eb67d #1 id=0x7f0c0050}
moveto ACTIVITY_CREATED: DetailFragment{83eb67d #1 id=0x7f0c0050}
moveto STARTED: DetailFragment{83eb67d #1 id=0x7f0c0050}
moveto RESUMED: DetailFragment{83eb67d #1 id=0x7f0c0050}
日志对应场景3
从DetailFragment
中点击返回,使得回退栈回退重新回到DispatchFragment
。
// Step 1:
popFromBackStack: BackStackEntry{50f64d4 #1}
= mName=null mIndex=1 mCommitted=true
= Operations:
= Op #0: REPLACE DetailFragment{83eb67d #1 id=0x7f0c0050}
// 注意此处 Removed DispatchFragment;对应上面的 nest = 2;
= Removed: DispatchFragment{9943e5b #0 id=0x7f0c0050}
// Step 2:
Bump nesting in BackStackEntry{50f64d4 #1} by -1
Bump nesting of DetailFragment{83eb67d #1 id=0x7f0c0050} to 0
Bump nesting of DispatchFragment{9943e5b #0 id=0x7f0c0050} to 1
// Step 3:
remove: DetailFragment{83eb67d #1 id=0x7f0c0050} nesting=0
movefrom RESUMED: DetailFragment{83eb67d #1 id=0x7f0c0050}
movefrom STARTED: DetailFragment{83eb67d #1 id=0x7f0c0050}
movefrom STOPPED: DetailFragment{83eb67d #1 id=0x7f0c0050}
movefrom ACTIVITY_CREATED: DetailFragment{83eb67d #1 id=0x7f0c0050}
movefrom CREATED: DetailFragment{83eb67d #1 id=0x7f0c0050}
Freeing fragment index DetailFragment{83eb67d #1 id=0x7f0c0050}
add: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto ACTIVITY_CREATED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto ACTIVITY_CREATED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
moveto ACTIVITY_CREATED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
moveto STARTED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto STARTED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
moveto STARTED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
moveto RESUMED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto RESUMED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
moveto RESUMED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
Freeing back stack index 1
日志对应场景4
ViewPager
的水平滑动。
Freeing fragment index ViewPagerChildFragment{47621c3 #2 id=0x7f0c0051}
// Step 1:
Commit: BackStackEntry{3f27a6c}
= mName=null mIndex=-1 mCommitted=false
= Operations:
= Op #0: ADD ViewPagerChildFragment{b133835 id=0x7f0c0051}
// Step 2:
Run: BackStackEntry{3f27a6c}
add: ViewPagerChildFragment{b133835 id=0x7f0c0051}
Allocated fragment index ViewPagerChildFragment{b133835 #2 id=0x7f0c0051}
// Step 3:
moveto CREATED: ViewPagerChildFragment{b133835 #2 id=0x7f0c0051}
moveto ACTIVITY_CREATED: ViewPagerChildFragment{b133835 #2 id=0x7f0c0051}
moveto STARTED: ViewPagerChildFragment{b133835 #2 id=0x7f0c0051}
moveto RESUMED: ViewPagerChildFragment{b133835 #2 id=0x7f0c0051}
DispatchFragment 使用了2次?
// DispatchFragment nest 的次数 = 1
Run: BackStackEntry{2f4c96a #0}
Bump nesting in BackStackEntry{2f4c96a #0} by 1
###Bump nesting of DispatchFragment{9943e5b id=0x7f0c0050} to 1
add: DispatchFragment{9943e5b id=0x7f0c0050}
Allocated fragment index DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto CREATED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto ACTIVITY_CREATED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto STARTED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto RESUMED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto CREATED: ViewPagerChildFragment{7094009 id=0x7f0c0051}
// 省略部分日志
Commit: BackStackEntry{50f64d4}
mName=null mIndex=-1 mCommitted=false
Operations:
Op #0: REPLACE DetailFragment{83eb67d id=0x7f0c0050}
Setting back stack index 1 to BackStackEntry{50f64d4}
Run: BackStackEntry{50f64d4 #1}
Bump nesting in BackStackEntry{50f64d4 #1} by 1
Bump nesting of DetailFragment{83eb67d id=0x7f0c0050} to 1
OP_REPLACE: adding=DetailFragment{83eb67d id=0x7f0c0050} old=DispatchFragment{9943e5b #0 id=0x7f0c0050}
### Bump nesting of DispatchFragment{9943e5b #0 id=0x7f0c0050} to 2
popFromBackStack: BackStackEntry{50f64d4 #1}
mName=null mIndex=1 mCommitted=true
Operations:
Op #0: REPLACE DetailFragment{83eb67d #1 id=0x7f0c0050}
Removed: DispatchFragment{9943e5b #0 id=0x7f0c0050}
Bump nesting in BackStackEntry{50f64d4 #1} by -1
Bump nesting of DetailFragment{83eb67d #1 id=0x7f0c0050} to 0
###Bump nesting of DispatchFragment{9943e5b #0 id=0x7f0c0050} to 1
remove: DetailFragment{83eb67d #1 id=0x7f0c0050} nesting=0
movefrom RESUMED: DetailFragment{83eb67d #1 id=0x7f0c0050}
movefrom STARTED: DetailFragment{83eb67d #1 id=0x7f0c0050}
movefrom STOPPED: DetailFragment{83eb67d #1 id=0x7f0c0050}
movefrom ACTIVITY_CREATED: DetailFragment{83eb67d #1 id=0x7f0c0050}
movefrom CREATED: DetailFragment{83eb67d #1 id=0x7f0c0050}
Freeing fragment index DetailFragment{83eb67d #1 id=0x7f0c0050}
add: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto ACTIVITY_CREATED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto ACTIVITY_CREATED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
moveto ACTIVITY_CREATED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
moveto STARTED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto STARTED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
moveto STARTED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
moveto RESUMED: DispatchFragment{9943e5b #0 id=0x7f0c0050}
moveto RESUMED: ViewPagerChildFragment{7094009 #0 id=0x7f0c0051}
moveto RESUMED: ViewPagerChildFragment{edec42f #1 id=0x7f0c0051}
Freeing back stack index 1