前言
上一篇我们通过一个简单demo初步认识了分屏模式。本篇文章我们先具体来看下全屏和分屏场景下的层级树信息,并对二者做个简单比较,以便对分屏模式的实现方案有个更深入的认识。
全屏模式层级树信息
全屏模式下层级树的DefaultTaskDisplayArea节点信息如下所示。
#1 DefaultTaskDisplayArea type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#2 Task=8 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#0 ActivityRecord{f6cfd18 u0 com.example.myapplication/.MainActivity t8} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#0 40df6b5 com.example.myapplication/com.example.myapplication.MainActivity type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#1 Task=1 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#0 Task=7 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#0 ActivityRecord{58c8437 u0 com.android.launcher3/.uioverrides.QuickstepLauncher t7} type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#0 324fb94 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#0 Task=2 type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#1 Task=4 type=undefined mode=multi-window override-mode=multi-window requested-bounds=[0,2400][1080,3600] bounds=[0,2400][1080,3600]
#0 Task=3 type=undefined mode=multi-window override-mode=multi-window requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
在全屏模式下MainActivity的相关信息如下:
- 根Task的mode=fullscreen(全屏模式),bounds=[0,0][1080,2400]
- 父节点ActivityRecord的mode=fullscreen(全屏模式),bounds=[0,0][1080,2400]
- MainActivity的mode=fullscreen(全屏模式),bounds=[0,0][1080,2400]
分屏模式层级树信息
分屏模式下层级树的DefaultTaskDisplayArea节点信息如下所示。
#1 DefaultTaskDisplayArea type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#1 Task=2 type=standard mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#1 Task=3 type=standard mode=multi-window override-mode=multi-window requested-bounds=[0,1213][1080,2400] bounds=[0,1213][1080,2400]
#0 Task=9 type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1213][1080,2400]
#0 ActivityRecord{d7a81a6 u0 com.android.dialer/.main.impl.MainActivity t9} type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1213][1080,2400]
#0 a2bfc4a com.android.dialer/com.android.dialer.main.impl.MainActivity type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1213][1080,2400]
#0 Task=4 type=standard mode=multi-window override-mode=multi-window requested-bounds=[0,0][1080,1187] bounds=[0,0][1080,1187]
#0 Task=8 type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,1187]
#0 ActivityRecord{f6cfd18 u0 com.example.myapplication/.MainActivity t8} type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,1187]
#0 40df6b5 com.example.myapplication/com.example.myapplication.MainActivity type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,1187]
#0 Task=1 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#0 Task=7 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#0 ActivityRecord{58c8437 u0 com.android.launcher3/.uioverrides.QuickstepLauncher t7} type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
#0 324fb94 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2400]
在分屏窗口模式下MainActivity的相关信息如下:
- 处于分屏模式的的两个Activity共用一个根Task。
- 每个Activity的父节点是ActivityRecord,然后又连续被两个Task包裹,最终共同挂载在一个Task上,该Task再挂载到DefaultTaskDisplayArea节点上。
分屏模式SurfaceFlinger信息
Display 4619827259835644672 (active) HWC layers:
---------------------------------------------------------------------------------------------------------------------------------------------------------------
Layer name
Z | Window Type | Comp Type | Transform | Disp Frame (LTRB) | Source Crop (LTRB) | Frame Rate (Explicit) (Seamlessness) [Focused]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
com.example.myapplication/com.example.myapplication.MainActivity#179
rel 0 | 1 | DEVICE | 0 | 0 0 1080 1187 | 0.0 0.0 1080.0 1187.0 | [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
com.android.dialer/com.android.dialer.main.impl.MainActivity#180
rel 0 | 1 | DEVICE | 0 | 0 1213 1080 2400 | 0.0 0.0 1080.0 1187.0 | [*]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
StageCoordinatorSplitDivider#187
rel 0 | 0 | DEVICE | 0 | 0 1137 1080 1263 | 0.0 0.0 1080.0 126.0 | [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
StatusBar#84
rel 0 | 2000 | DEVICE | 0 | 0 0 1080 63 | 0.0 0.0 1080.0 63.0 | [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
NavigationBar0#83
rel 0 | 2019 | DEVICE | 0 | 0 2274 1080 2400 | 0.0 0.0 1080.0 126.0 | [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
- StageCoordinatorSplitDivider 分屏模式中间的分割线视图
总结
- 当应用Activity处于全屏模式的时候,其父类ActivityRecord,ActivityRecord的父类为Task,该Task直接挂载在DefaultTaskDisplayArea节点上。
- 当应用Activity处于分屏模式的时候,其父类为ActivityRecord,该Task没有直接挂载到直接挂载在DefaultTaskDisplayArea节点上,而是连续被两个Task包裹,最终共同挂载在同一个根Task上,然后该根Task直接挂载在DefaultTaskDisplayArea叶子节点上。
- 当处于分屏模式的时候,系统会添加一个名为StageCoordinatorSplitDivider的分割线视图。
理解了这点,后面我们再结合Android系统任务栈的特性,才能够更好的理解分屏模式框架的实现思路。
💡 技术无价,赞赏随心
写文不易,如果本文帮你避开了“八小时踩坑”,或者让你直呼“学到了!”
欢迎扫码赞赏,让我知道这篇内容值得!