网站备案要花钱吗,吉林智能网站建设找哪家,php mysql 网站建设,工商咨询服务在安卓源码的设计中#xff0c;将将屏幕分为了37层#xff0c;不同的窗口将在不同的层级中显示。 对这一块的概念以及相关源码做了详细分析#xff0c;整理出以下几篇。 
【Android 13源码分析】WindowContainer窗口层级-1-初识窗口层级树 
【Android 13源码分析】WindowCon…在安卓源码的设计中将将屏幕分为了37层不同的窗口将在不同的层级中显示。 对这一块的概念以及相关源码做了详细分析整理出以下几篇。 
【Android 13源码分析】WindowContainer窗口层级-1-初识窗口层级树 
【Android 13源码分析】WindowContainer窗口层级-2-构建流程 
【Android 13源码分析】WindowContainer窗口层级-3-实例分析 
【Android 13源码分析】WindowContainer窗口层级-4-Surface树 
当前为第一篇主要是基础知识介绍。 
打开“电话应用”然后按音量键出现一下界面  提出2个问题 
为什么音量窗口会挡住应用窗口为什么不管打开哪个应用都能看到导航栏和状态栏 
再看下面这个图 左边是将第一张截图的每一个窗口提出来画了的模拟图 想象一下每个窗口其实都是全屏的那么他的前后顺序若右图注意颜色是对应的。 如果说是按右边的这种层级排序那么音量键的窗口和状态栏的窗口就会挡住Activity的窗口。 
在安卓中窗口是有先后顺序的越靠近用户的就越靠前就能挡住底下的窗口。 目前说这么一个结论可能为时过早后面的内容将详细介绍。 
1. 基础知识介绍 
1.1 三维空间概念 
1.1.1 三维空间概念–游戏3D世界 
下面2个图来自Unity3d官网开发文档:  们玩的王者荣耀原神等游戏的开发都是类似在这么一个3D场景下进行的开发者将使用3D建模工具来创建地形、建筑、植被等地图元素并通过材质和贴图来增强地图的视觉效果。 
比如这张图片里放了3个颜色的柱子。 除了这些物体外可以看到还有一个摄像机Camera它是用来捕捉画面的 毕竟手机屏幕是2D的简单来说这个摄像机能捕捉到的画面就是我们手机屏幕上显示的内容比如这张图片捕捉到的画面是右下角的内容。 
像我们玩游戏移动角色其实就是通过转动这个摄像机Camera来完成的。 
下面这种图会更加像一个游戏的画面一些。 通过看游戏地图的3D开发场景就是希望能狗更加生动的理解到在2D的手机屏幕下其实有一个3D的空间虽然我们的安卓开发不会像游戏开发那么复杂但是原理也是一样的。 
1.1.2 三维空间概念–Android的三维坐标系 Android坐标系其实就是一个三维坐标Z轴向上X轴向右Y轴向下。 
经常听到的 Z-Order 也就是指窗口在Z轴的排序离用户越近Z值越大。并且能够遮挡住后面的窗口。 
为了再加深一下安卓窗口的层级关系下面看一张应用开发的View层级的3D视角。 
注意下面的图片是View不是本次要讲的窗口只是为了加深一下层级印象 可以看到在布局了写了37层约束布局其实第3层加了一个按钮。 右上角我们手机屏幕上只是一个按钮的界面但是右下角通过Android Studio自带的工具可以发现整个View树是有很多层的代码写了37层。 
这里看到的View层级其实和后面要讲就窗口分层是有相似之处的。 将这里是37层想象层安卓在窗口的分层也是可以的。 
1.2 ViewTree 
为了后续方便理解窗口树 先介绍一下安卓开发都知道的View树  XML里如图写下2个简单的红绿布局显示的UI效果绿色的会挡住一部分红色的。但是用工具其实可以发送红色控件其实也是完成绘制的。  也就是说在同一层级下在ViewGropu孩子View数组这个集合中下标越大的View会挡住后面的View。也可以理解层 层级越靠前就会当初后面的View。 
继续增加几个View 控件B下新增控件DD下面放了一个文本控件G  控件C下面新增了一个文本控件F  左边看到对View做了层级处理这个就是ViewTree可以将其画成树图  这个就是View层的View树能构建出View树的原因是因为在代码中定义了ViewGroup这个类 
# View// 父容器protected ViewParent mParent;# ViewGroup// 所有子Viewprivate View[] mChildren;public void addView(View child, int index) {......// 内部实现是通过addInArray 将View添加到数组mChildren中addView(child, index, params);}Overridepublic void removeView(View view) {......// 本质还是从mChildren移除}应用布局用的场景的几个类他们都有一个共同的父类–ViewGroup。 
ViewGroup继承了View,所以有父亲mParent自身内部又维护了一个View数组mChildren表示它的孩子们。 上有父亲下有一群孩子所以能构建出一个ViewTree。 
如果只有一个孩子那是线性结构因此孩子必须是多个所以ViewGroup也是一个View的容器类。 有这么一个类的存在开发者就可以通过嵌套来行程一个非常复杂的ViewTree结构 这也是应用开发者能写出各种丰富UI的基础。 
在窗口这一级别的开发中也有窗口树也有对应的容器结构。 后面会详细解释窗口容器类在介绍之前先了解一下什么是窗口。 
ViewTree在代码中也是真实存在的在Activity中通过以下代码对应ViewTree的变化做监听 View.getViewTreeObserver().addOnGlobalLayoutListener(......)1.3 什么是窗口 
从视觉上用户在手机屏幕上看到的“一块区域”就是一个窗口比如前面看到的这张图每一块都是一个窗口 从代码上来说应用端的窗口指的是Window framework层的窗口指的是WindowState  为什么会用不一样的类来表示“窗口”呢 
比如说有一个人他是唯一的身份证号是他的唯一表示但是他在不同的系统中保存的他的数据是不一样的比如在公司公司系统对这个人保存的个人基本信息在交警系统保存的是这个人的车辆信息和违章信息。  在生活中不同系统对一个人关注保存的数据是不一样在代码中也是一样的。应用开发者为了降低模块的依赖也会有这种设计。 
2. 初识窗口层级树 
2.1 窗口容器类介绍 
前面看到了一些View树构建的类也就是我们说的常见布局现在列举构建窗口树用的的几个容器类。 WindowContainer 
类似ViewGroup的存在是窗口容器的基类后面介绍的其他窗口容器类都是它的子类。 
有泛型限制说明容器的内容是有限制的 
mParent 保存当前容器的父窗口引用。 
mChildren 保存当前窗口的所有孩子窗口容器集合有泛型。根据注释列表后面的子容器z-order 越大离屏幕越近。 
父类为ConfigurationContainer封装了配置的处理当前类封装了容器的操作。 RootWindowContainer* 
根窗口容器也是窗口层级树的根管理DisplayContent。  DisplayContent 
代表一个屏幕Android是支持多屏幕的。 
继承关系为 DisplayContent-RootDisplayArea-DisplayArea.Dimmable-DisplayArea-WindowContainer 
孩子为DisplayArea这个规则定义在DisplayArea的子类Dimmable中 WindowState 
代表一个窗口本身也是一个容器比如子窗口就是它的孩子Popupwindow场景  DisplayArea 注释DisplayContent下的窗口容器集合。 
说人话表示一块显示区域是DisplayContent的子容器。DisplayContent下安卓目前设计为分了37层每一层都是一个DisplayArea。 
有三个直接子类TaskDisplayAreaDisplayArea.Tokens和DisplayArea.Tokens。 TaskDisplayArea 
注释孩子可以是Task或者是TaskDisplayArea。不过目前看到的孩子都是Task类型。 
对应层级树的第二层专门用来存放应用的窗口图层非常重要APP的窗口都在这。也是窗口层级树看的重点区域。 DisplayArea.Token 
DisplayArea的子类并且是其内部类表示WindowToken的容器。WindowToken的子类是WindowState DisplayArea.Dimmable 
DisplayArea的子类并且是其内部类DisplayContent的父类带模糊效果。孩子是DisplayArea。 ImeContainer 
输入法容器父类是DisplayArea.Token那么孩子也是WindowToken。输入法专用 Task 
父类TaskFragment继承WindowContainer泛型没有限制孩子的类型。但是实际情况下孩子是Task和ActivityRecord类型。 
开发过程中经常见到的类也是应用开发多窗口开发经常会遇到的。 WindowToken 
理器中一组相关窗口的容器是窗口的Token,而窗口的定义WindowState。一般在窗口层级树中WindowToken下面就会挂载一个WindowState。 
壁纸用到的WallpaperWindowToken也是其子类。 ActivityRecord 
对应着一个Activity。 
是WindowToken的子类所以孩子也是WindowState。 从应用开发角度一个Activity下也有一个Window。并且一般作为是Task的孩子。 
2.2 Feature介绍 
为什么有这个Feature(特征)呢 
AOSP既然将屏幕分了37层那说明图层之间是有区别的有不一样的特性这个就是Feature比如这一层是不是支持单手操作。 这里列举5个常见的Feature已经它们所在的层级。 
WindowedMagnification 
拥有特征的层级 0-31
特征描述 支持窗口缩放的一块区域一般是通过辅助服务进行缩小或放大HideDisplayCutout 
拥有特征的层级 0-14 16 18-23 26-35 特征描述隐藏剪切区域即在默认显示设备上隐藏不规则形状的屏幕区域比如在代码中打开这个功能后有这个功能的图层就不会延伸到刘海屏区域。 
OneHanded 
拥有特征的层级0-23 26-32 34-35 特征描述表示支持单手操作的图层这个功能在手机上还是挺常见的 
FullscreenMagnification 
拥有特征的层级0-12 15-23 26-27 29-31 33-35 特征描述支持全屏幕缩放的图层和上面的不同这个是全屏缩放前面那个可以局部 
ImePlaceholder 
拥有特征的层级 13-14 特征描述输入法相关 3 WMS的层级结构树 
可以通过以下命令来看获取到设备当前的层级结构树 
adb shell dumpsys activity containers在开完机后的launcher就执行了dump命令然后就能得到下面这么一段输出乍一看很容易劝退但是实际上这些东西都是有规律而且很简单。目前可以先不看稍后再详细解释。 
ACTIVITY MANAGER CONTAINERS (dumpsys activity containers)
ROOT typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Display 0 nameBuilt-in Screen typeundefined modefullscreen override-modefullscreen requested-bounds[0,0][720,1600] bounds[0,0][720,1600]#2 Leaf:36:36 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 WindowToken{451b2bd type2024 android.os.BinderProxy4526826} typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 47e1803 ScreenDecorOverlayBottom typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 WindowToken{69b9325 type2024 android.os.BinderProxy3a8ab1c} typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 799b2ab ScreenDecorOverlay typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 HideDisplayCutout:32:35 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#2 OneHanded:34:35 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 FullscreenMagnification:34:35 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:34:35 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 FullscreenMagnification:33:33 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:33:33 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 OneHanded:32:32 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:32:32 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 WindowedMagnification:0:31 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#6 HideDisplayCutout:26:31 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 OneHanded:26:31 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#2 FullscreenMagnification:29:31 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:29:31 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 Leaf:28:28 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 FullscreenMagnification:26:27 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:26:27 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#5 Leaf:24:25 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 WindowToken{922c2bc type2024 android.os.BinderProxyd50168e} typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 48a6245 pip-dismiss-overlay typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 WindowToken{1a3a19a type2019 android.os.BinderProxy1ec36bc} typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 50a3d66 NavigationBar0 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#4 HideDisplayCutout:18:23 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 OneHanded:18:23 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 FullscreenMagnification:18:23 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:18:23 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#3 OneHanded:17:17 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 FullscreenMagnification:17:17 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:17:17 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 WindowToken{7472fe2 type2040 android.os.BinderProxy1bfb9c4} typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 4b26f73 NotificationShade typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#2 HideDisplayCutout:16:16 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 OneHanded:16:16 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 FullscreenMagnification:16:16 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:16:16 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 OneHanded:15:15 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 FullscreenMagnification:15:15 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:15:15 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 WindowToken{3da7d5c type2000 android.os.BinderProxye2c682e} typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 7619865 StatusBar typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 HideDisplayCutout:0:14 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 OneHanded:0:14 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 ImePlaceholder:13:14 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 ImeContainer typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 WindowToken{1397896 type2011 android.os.Binder23bebb1} typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 d0c3c51 InputMethod typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 FullscreenMagnification:0:12 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#2 Leaf:3:12 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 WindowToken{82fa61a type2038 android.os.BinderProxy2f86adc} typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 33a873c ShellDropTarget typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 DefaultTaskDisplayArea typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#2 Task1 typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Task7 typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 ActivityRecord{bd2b1d4 u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t7} typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 ae1df9b com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 b9fa2f0 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 Task2 typeundefined modefullscreen override-modefullscreen requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Task3 typeundefined modefullscreen override-modefullscreen requested-bounds[0,0][0,0] bounds[0,0][720,1600]#1 Task6 typeundefined modemulti-window override-modemulti-window requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Task5 typeundefined modemulti-window override-modemulti-window requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Leaf:0:1 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 WallpaperWindowToken{4b4c99a tokenandroid.os.Binder9258e45} typeundefined modefullscreen override-modefullscreen requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 f3495ce com.android.systemui.ImageWallpaper typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]先看看点击桌面的“电话“进入电话界面后再执行这个dump命令有什么区别 tips: com.google.android.dialer 这个包名是电话这个应用 这个区别就比较好看出来了在#1 DefaultTaskDisplayArea下多了一些东西。看到里面也知道这个是增加一些与“电话”这个应用的Activity相关的东西。 然后再按一下音量键盘看一下区别 在其他的场景比如按power出现的弹窗 出现toast的时候或者进入分屏都可以进行dump对比一下差异。 现在可以有以下信息 
开完机层级结构树就存在界面上有相关的Window的操作都会在层级结构树上体现不同的window会被挂在到对应的位置这个其实就是层级结构树的关键。 当然哪个Window应该挂在到那一层怎么个先后顺序这个我们其实无需过于在意这个是产品设计。 
tips: 可以试试不同Activity启动模式后的区别 
3.1 简单分析层级结构树 
现在来分析上面那一团输出信息怎么看。从上到下从左往右 
ROOT typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]#0 Display 0 nameBuilt-in Screen typeundefined modefullscreen override-modefullscreen requested-bounds[0,0][720,1600] bounds[0,0][720,1600]上面的ROOT 表示根节点暂时可以忽略。下面的 #0 Display 0 nameBuilt-in Screen表示当前的手机的第0个屏幕目前也可忽略主要是下面那一部分内容。 下面的内容虽然很长但是我们不要看全部抓住几个点就够了以前面这段为例 #2 Leaf:36:36 typeundefined modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][720,1600]1. 看所在位置 #X 
每一行最前面都是 “#数字”的形式打头比如现在看的是 “#2 Leaf:36:36”这里的数字表示这个图层在当前父容器的位置从0开始。其实和ViewGrop或许childView的一样的。 当前这个为#2 所以他的父容器一共有3个子容器当前这个处于第三个也就是最上面。那么和他同级的另外2个怎么找呢 需要往下看找到和当前 #2 前面空格一样多的#1 和#0 就是他同级的2个容器了按照规则能能找下面这2个与他同级的。 需要注意这里说的同级并不是在同一图层而是在层级树这个树的结构是同级关系 
#1 HideDisplayCutout:32:35
#0 WindowedMagnification:0:312. 层级name 名字起始层级结束层级 指的是 “Leaf:36:36” 这一段信息这个的格式为“容器名 起始层级:结束层级” 体现在当前就是这个 #2 的容器叫 “Leaf”,表示一个叶子节点比较特殊主要看后面的频繁出现的HideDisplayCutoutImePlaceholderOneHanded等这些都有具体的意义我们知道所有的东西在源码中都能找到对应的代码 像提到的HideDisplayCutoutImePlaceholderOneHanded在源码中称之为Feature特征即表示当前这个容器有具有这个特征暂时知道就可以后面会详细介绍源码对这些Feature的具体定义。 然后就是后面的起始层级:结束层级因为虽然一共是分为37层但是并不是说有37个Feature比如“#1 ImePlaceholder:13:14 ” ImePlaceholder看着就是和输入法相关那就代表着1314都是和输入法相关的window。 android 13目前一共也只有5个Feature。 
另外提一下这里的 “Leaf”代表的不是Feature而且说当前是某个叶子节点下面是要挂着具体Window的。 
3. 看其他属性比如typemode 
知道上面这4点基本上就能看到层级结构树的信息了内容虽然很多但是我们其实主要关心的还是下面“#1 DefaultTaskDisplayArea”的部分因为这里放的才是应用相关的窗口其他的一般都是系统窗口。像应用操作分屏小窗自由窗口操作导致层级改变都体现在这一层 另外可以留意一下如果是 WindowToken WindowState的都是系统窗口比如下面这种形式 #0 WindowToken{1397896#0 d0c3c51 InputMethodd0c3c51 这个应该是WindowState的对象名后面的InputMethod是具体的窗口名 而 ActivityRecordWindowState就是应用了比如 #0 ActivityRecord{91c971c#0 9c20028 com.google.android.dialer这些有个印象就行不需要硬背以后看的多了自然就有感觉了。 
3.2 层级结构树可视化 
单看层级树可能过于枯燥在刚开始学习的时候一般都会根据信息画出一个层级结构图。 首先根据前面看dump内容的方式先画出一部分内容如下 这里是DisplayContent下的3个孩子可以看到已经覆盖了 0-36层。 然后按照这种方式将所有的内容都画出来就可以得到下面这完整的树图 强烈建议想学这一块的同学一定要手动画出这么一个图 
android版本相同画出来的图基本上都是一样的只会根据出现不同的Window在响应的Leaf,也就是叶子节点会有不同。 这里将叶子节点的颜色涂上了发现叶子节点下要么为空要么就是 WindowToken除了最底层的壁纸其实壁纸叶子节点下的WallpaperWindowToken这个类也是继承的WindowToken。 
可能之前通过文本的形式还有点陌生但是转换成图片后一些常见的东西就都清楚了比如launcher,StatusBar,NavigationBar,Wallpaper 
窗口树和View树还是有差距的View树上都是View而窗口树上只有叶子节点上挂着窗口其他大都都是一些容器和一些。 
窗口树是固定37层的 然后各个图层都有自己支持的Feature这些都是代码中固定好的。 实际开发中开发中再将自己的窗口根据需求挂到对应的叶子节点上这个和View树是有区别的。 
3.3 为什么这么设计 
方便管理 在写应用的时候也会这样定义这样如果说某个业务的View无论怎么写他就只能在自己所在的“层级”上显示不会影响到其他。 
窗口这样设计的原因可能还有其他的考虑在远古时期窗口的顺序好像是经过规则计算的那么这种计算很麻烦出了问题也不好定位。 
现在的这种设计就很合理符合“单一原则”各个类型的窗口在自己的层级上不会影响到其他。 
方便功能开发 另外一个优点我认为是这种设计为小窗分屏这种功能提供了开发的便利因为只需要将对应的窗口移动到所在的Task就可以了。 
像现在的Activity启动在system_service进程的处理的很多逻辑都是围绕着这个层级树来做的。 比如看一眼“电话”和“短信”2个应用进行分屏操作的前后对比 通过对比可以发现 
Task5,6 这2个Task是分屏用到的Task,它们有共同的父亲-- Task 4。 这3个Task 在开机的时候就创建好了默认在DefaultTaskDisplayArea孩子里是最后面。启动分屏后其实对应窗口容器这边做了2件事 将Task4 移到栈顶将2个分屏应用的Task分别移到到Task5,6 下  
这样分屏就完成了。 文章转载自: http://www.morning.weitao0415.cn.gov.cn.weitao0415.cn http://www.morning.tqxtx.cn.gov.cn.tqxtx.cn http://www.morning.trmpj.cn.gov.cn.trmpj.cn http://www.morning.jzykw.cn.gov.cn.jzykw.cn http://www.morning.qiyelm.com.gov.cn.qiyelm.com http://www.morning.wqngt.cn.gov.cn.wqngt.cn http://www.morning.jmmz.cn.gov.cn.jmmz.cn http://www.morning.hmjasw.com.gov.cn.hmjasw.com http://www.morning.sqqdy.cn.gov.cn.sqqdy.cn http://www.morning.nccyc.cn.gov.cn.nccyc.cn http://www.morning.pdtjj.cn.gov.cn.pdtjj.cn http://www.morning.cxtbh.cn.gov.cn.cxtbh.cn http://www.morning.mgbsp.cn.gov.cn.mgbsp.cn http://www.morning.zcmpk.cn.gov.cn.zcmpk.cn http://www.morning.xkzmz.cn.gov.cn.xkzmz.cn http://www.morning.tgcw.cn.gov.cn.tgcw.cn http://www.morning.sqfnx.cn.gov.cn.sqfnx.cn http://www.morning.pxsn.cn.gov.cn.pxsn.cn http://www.morning.wwjft.cn.gov.cn.wwjft.cn http://www.morning.wsyq.cn.gov.cn.wsyq.cn http://www.morning.pdbgm.cn.gov.cn.pdbgm.cn http://www.morning.spfh.cn.gov.cn.spfh.cn http://www.morning.kpcdc.cn.gov.cn.kpcdc.cn http://www.morning.fsqbx.cn.gov.cn.fsqbx.cn http://www.morning.nqypf.cn.gov.cn.nqypf.cn http://www.morning.trnhy.cn.gov.cn.trnhy.cn http://www.morning.zcwzl.cn.gov.cn.zcwzl.cn http://www.morning.zxrtt.cn.gov.cn.zxrtt.cn http://www.morning.ptzf.cn.gov.cn.ptzf.cn http://www.morning.bpmmq.cn.gov.cn.bpmmq.cn http://www.morning.nrll.cn.gov.cn.nrll.cn http://www.morning.lwlnw.cn.gov.cn.lwlnw.cn http://www.morning.ptzf.cn.gov.cn.ptzf.cn http://www.morning.mhwtq.cn.gov.cn.mhwtq.cn http://www.morning.tnhg.cn.gov.cn.tnhg.cn http://www.morning.ylxgw.cn.gov.cn.ylxgw.cn http://www.morning.ppghc.cn.gov.cn.ppghc.cn http://www.morning.bfgbz.cn.gov.cn.bfgbz.cn http://www.morning.sfwd.cn.gov.cn.sfwd.cn http://www.morning.dtnjr.cn.gov.cn.dtnjr.cn http://www.morning.fqyqm.cn.gov.cn.fqyqm.cn http://www.morning.fnmtc.cn.gov.cn.fnmtc.cn http://www.morning.ljbpk.cn.gov.cn.ljbpk.cn http://www.morning.qtqk.cn.gov.cn.qtqk.cn http://www.morning.dzgyr.cn.gov.cn.dzgyr.cn http://www.morning.c7625.cn.gov.cn.c7625.cn http://www.morning.mcwgn.cn.gov.cn.mcwgn.cn http://www.morning.yuanshenglan.com.gov.cn.yuanshenglan.com http://www.morning.sfdky.cn.gov.cn.sfdky.cn http://www.morning.xglgm.cn.gov.cn.xglgm.cn http://www.morning.jkzq.cn.gov.cn.jkzq.cn http://www.morning.pkfpl.cn.gov.cn.pkfpl.cn http://www.morning.cnqff.cn.gov.cn.cnqff.cn http://www.morning.pbmg.cn.gov.cn.pbmg.cn http://www.morning.spnky.cn.gov.cn.spnky.cn http://www.morning.prmbn.cn.gov.cn.prmbn.cn http://www.morning.rldph.cn.gov.cn.rldph.cn http://www.morning.kpcjl.cn.gov.cn.kpcjl.cn http://www.morning.pyxwn.cn.gov.cn.pyxwn.cn http://www.morning.sgnjg.cn.gov.cn.sgnjg.cn http://www.morning.rlbfp.cn.gov.cn.rlbfp.cn http://www.morning.rwlsr.cn.gov.cn.rwlsr.cn http://www.morning.dfndz.cn.gov.cn.dfndz.cn http://www.morning.wcqkp.cn.gov.cn.wcqkp.cn http://www.morning.xbptx.cn.gov.cn.xbptx.cn http://www.morning.rczrq.cn.gov.cn.rczrq.cn http://www.morning.wwwghs.com.gov.cn.wwwghs.com http://www.morning.sbwr.cn.gov.cn.sbwr.cn http://www.morning.ntgsg.cn.gov.cn.ntgsg.cn http://www.morning.zlcsz.cn.gov.cn.zlcsz.cn http://www.morning.ftdlg.cn.gov.cn.ftdlg.cn http://www.morning.dbfwq.cn.gov.cn.dbfwq.cn http://www.morning.zymgs.cn.gov.cn.zymgs.cn http://www.morning.xxwhz.cn.gov.cn.xxwhz.cn http://www.morning.lrwsk.cn.gov.cn.lrwsk.cn http://www.morning.rqbr.cn.gov.cn.rqbr.cn http://www.morning.pwlxy.cn.gov.cn.pwlxy.cn http://www.morning.dyrzm.cn.gov.cn.dyrzm.cn http://www.morning.hrpjx.cn.gov.cn.hrpjx.cn http://www.morning.yhglt.cn.gov.cn.yhglt.cn