Android T 窗口层级其一 —— 容器类

窗口在App端是以PhoneWindow的形式存在,承载了一个Activity的View层级结构。这里我们探讨一下WMS端窗口的形式。
可以通过adb shell dumpsys activity containers 来看窗口显示的层级

窗口容器类 —— WindowContainer类

/*** Defines common functionality for classes that can hold windows directly or through their* children in a hierarchy form.* The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime* changes are made to this class.*/
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable,InsetsControlTarget {....../*** The parent of this window container.* For removing or setting new parent {@link #setParent} should be used, because it also* performs configuration updates based on new parent's settings.*/private WindowContainer<WindowContainer> mParent = null;......// List of children for this window container. List is in z-order as the children appear on// screen with the top-most window container at the tail of the list.protected final WindowList<E> mChildren = new WindowList<E>();

WindowContainer注释中开头就说明了其作用,即给可以直接持有窗口的自己或它的孩子定义了一些公共的方法和属性。
WindowContainer定义了能够直接或者间接以层级结构的形式持有窗口的类的通用功能。
从类的定义和名称,可以看到WindowContainer是一个容器类,可以容纳WindowContainer及其子类对象。如果另外一个容器类作为WindowState的容器,那么这个容器类需要继承WindowContainer或其子类。

其中mParent和mChildren,一个代表父节点一个代表子节点,而且子节点的list顺序代表就是z轴的层级显示顺序,list尾巴在比list的头的z轴层级要高。
1)mParent是WindowContainer类型成员变量,保存的是当前WindowContainer的父容器的引用。
2)mChildren是WindowList类型的成员变量,保存的则是当前WindowContainer持有的所有子容器。并且列表的顺序也就是子容器出现在屏幕上的顺序,最顶层的子容器位于队尾。

根窗口容器 —— RootWindowContainer

/** Root {@link WindowContainer} for the device. */
public class RootWindowContainer extends WindowContainer<DisplayContent>

根窗口容器,树的根是它。通过它遍历寻找,可以找到窗口树上的窗口。它的孩子是DisplayContent。

屏幕 —— DisplayContent

/*** Utility class for keeping track of the WindowStates and other pertinent contents of a* particular Display.*/
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {

该类是对应着显示屏幕的,Android是支持多屏幕的,所以可能存在多个DisplayContent对象。上图只画了一个对象的结构,其他对象的结构也是和画的对象的结构是相似的。


RootWindowContainer代表dumpsys containers中ROOT ,DisplayContentdumpsys containers中Display,0表示当前显示的屏幕
在这里插入图片描述


窗口 —— WindowState类

/** A window in the window manager. */
class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState,InsetsControlTarget, InputTarget {

在WMS窗口体系中,一个WindowState对象就代表了一个窗口,其继承WindowContainer,这就说明WindowState同样可以作为其他窗口的父容器,例如我们常见的PopupWindow
在这里插入图片描述

WindowState的容器

可直接持有WindowState的容器即WindowToken和ActivityRecord,WallpaperWindowToken也可以持有WindowState,而其是继承WindowToken的

WindowToken类

/*** Container of a set of related windows in the window manager. Often this is an AppWindowToken,* which is the handle for an Activity that it uses to display windows. For nested windows, there is* a WindowToken created for the parent window to manage its children.*/
class WindowToken extends WindowContainer<WindowState> {

这个注释的意思大概是说:窗口管理器中一组相关窗口的容器。这通常是一个AppWindowToken,它是用于显示窗口的“活动”的句柄。对于嵌套窗口,会为父窗口创建一个WindowToken来管理其子窗口。
总而言之就是用WindowToken来管理WindowState
在这里插入图片描述

ActivityRecord类

/*** An entry in the history task, representing an activity.*/
public final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {

ActivityRecord是WindowToken的子类,在WMS中一个ActivityRecord对象就代表一个Activity对象

在这里插入图片描述

WallpaperWindowToken类

/*** A token that represents a set of wallpaper windows.*/
class WallpaperWindowToken extends WindowToken {

WallpaperWindowToken继承WindowToken,是用来存放和Wallpaper相关的窗口。
在这里插入图片描述


一般来说,一个窗口的父容器是WindowToken还是ActivityRecord,是否主动使用ViewManager.addView来添加一个窗口
父容器为WindowToken的情况:APP(含系统应用)主动调用添加窗口方法来添加窗口,如StatusBar、浮窗等。即非Activity窗口
父容器为ActivityRecord的情况:系统侧调用添加窗口方法来添加窗口,如在桌面启动一个应用等。即Activity窗口

从层级角度将窗口划分为:
App之上的窗口,父容器为WindowToken,如StatusBar和NavigationBar。
App窗口,父容器为ActivityRecord,如Launcher。
App之下的窗口,父容器为WallpaperWindowToken,如ImageWallpaper窗口


WindowToken的容器 —— DisplayArea.Tokens

    /*** DisplayArea that contains WindowTokens, and orders them according to their type.*/public static class Tokens extends DisplayArea<WindowToken> {

包含WindowTokens的容器Tokens,并根据其类型对其进行排序。

ActivityRecord的容器 —— Task

/*** {@link Task} is a TaskFragment that can contain a group of activities to perform a certain job.* Activities of the same task affinities usually group in the same {@link Task}. A {@link Task}* can also be an entity that showing in the Recents Screen for a job that user interacted with.* A {@link Task} can also contain other {@link Task}s.*/
class Task extends TaskFragment {

Task继承TaskFragment,它的孩子可以是Task,也可以是ActivityRecord类型。是一个TaskFragment,它可以包含一组执行特定作业的Activity。具有相同任务相似性的Activity通常在同一任务中分组。任务也可以是显示在用户交互的作业的最近屏幕中的实体。任务还可以包含其他任务。

/*** A basic container that can be used to contain activities or other {@link TaskFragment}, which* also able to manage the activity lifecycle and updates the visibilities of the activities in it.*/
class TaskFragment extends WindowContainer<WindowContainer> {

一个基本容器,可用于包含Activity或其他TaskFragment,它还能够管理Activity生命周期并更新其中活动的可见性。

Task的容器 —— TaskDisplayArea

/*** {@link DisplayArea} that represents a section of a screen that contains app window containers.** The children can be either {@link Task} or {@link TaskDisplayArea}.*/
final class TaskDisplayArea extends DisplayArea<WindowContainer> {

TaskDisplayArea,代表了屏幕上一块专门用来存放App窗口的区域。
它的子容器可能是Task或者是TaskDisplayArea。


在这里插入图片描述DefaultTaskDisplay是TaskDisplayArea的别名,在代码中有体现,后面说明
从这个dump中我们可以看到TaskDisplayArea下面就是Task,Task下面就是ActivityRecord且有多个,而ActivityRecord下面的a9a1d8b和c4b2818是各自的WindowState


DisplayArea类

/*** Container for grouping WindowContainer below DisplayContent.** DisplayAreas are managed by a {@link DisplayAreaPolicy}, and can override configurations and* can be leashed.** DisplayAreas can contain nested DisplayAreas.** DisplayAreas come in three flavors, to ensure that windows have the right Z-Order:* - BELOW_TASKS: Can only contain BELOW_TASK DisplayAreas and WindowTokens that go below tasks.* - ABOVE_TASKS: Can only contain ABOVE_TASK DisplayAreas and WindowTokens that go above tasks.* - ANY: Can contain any kind of DisplayArea, and any kind of WindowToken or the Task container.** @param <T> type of the children of the DisplayArea.*/
public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {

用于将WindowContainer分组到DisplayContent下方的容器。
DisplayArea由{@link DisplayAreaPolicy}管理,能够复写Configuration和被绑定到leash上。
DisplayArea可以包含嵌套的DisplayArea。
DisplayAreas有三种风格,以确保窗口具有正确的Z顺序:

  • BELOW_TASKS:只能包含位于任务下方的BELLOW_TASK显示区域和WindowToken。
  • ABOVE_TASKS:只能包含位于任务上方的ABOVE_TASK显示区域和WindowToken。
  • ANY:可以包含任何类型的DisplayArea,以及任何类型的WindowToken或Task容器。

@param<T>DisplayArea的子项的类型。

DisplayArea有三个直接子类,TaskDisplayArea,DisplayArea.Tokens和DisplayArea.Tokens

Task的容器 —— TaskDisplayArea

/*** {@link DisplayArea} that represents a section of a screen that contains app window containers.** The children can be either {@link Task} or {@link TaskDisplayArea}.*/
final class TaskDisplayArea extends DisplayArea<WindowContainer> {

TaskDisplayArea为DisplayContent的孩子,对应着窗口层次的第2层。第2层作为应用层,看它的定义:int APPLICATION_LAYER = 2,应用层的窗口是处于第2层。
TaskDisplayArea代表了屏幕上的一个包含App类型的WindowContainer的区域。它的子节点可以是Task,或者是TaskDisplayArea。

public DisplayAreaPolicy instantiate(WindowManagerService wmService,DisplayContent content, RootDisplayArea root,DisplayArea.Tokens imeContainer) {Inject.ResultOne<TaskDisplayArea> result = new Inject.ResultOne<>(new TaskDisplayArea(content, wmService,"DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER));

在DisplayAreaPolicy.java中有创建,并更名为DefaultTaskDisplayArea

WindowTokens的容器 —— DisplayArea.Tokens

    /*** DisplayArea that contains WindowTokens, and orders them according to their type.*/public static class Tokens extends DisplayArea<WindowToken> {

Tokens为DisplayArea的内部类,且继承DisplayArea。
即Tokens代表专门包含WindowTokens的容器,它的孩子是WindowToken,而WindowToken的孩子则为WindowState对象。WindowState是对应着一个窗口的。

输入法的容器 —— ImeContainer

    /*** Container for IME windows.** This has some special behaviors:* - layers assignment is ignored except if setNeedsLayer() has been called before (and no*   layer has been assigned since), to facilitate assigning the layer from the IME target, or*   fall back if there is no target.* - the container doesn't always participate in window traversal, according to*   {@link #skipImeWindowsDuringTraversal()}*/private static class ImeContainer extends DisplayArea.Tokens {

ImeContainer为DisplayContent.java的内部类,且继承DisplayArea.Tokens,即同样是一个WindowToken的容器,它的孩子是WindowToken类型。WindowToken的孩子为WindowState类型,而WindowState类型则对应着输入法窗口。
在这里插入图片描述

模糊效果 —— DisplayArea.Dimmable

    /*** DisplayArea that can be dimmed.*/static class Dimmable extends DisplayArea<DisplayArea> {private final Dimmer mDimmer = new Dimmer(this);

Dimmable也是DisplayArea的内部类,从名字可以看出,这类的DisplayArea可以添加模糊效果,并且Dimmable也是一个DisplayArea类型的DisplayArea容器。
可以通过Dimmer对象mDimmer施加模糊效果,模糊图层可以插入到以该Dimmable对象为根节点的层级结构之下的任意两个图层之间。
且它有一个直接子类,RootDisplayArea。

DisplayArea层级结构的根节点 —— RootDisplayArea

/*** Root of a {@link DisplayArea} hierarchy. It can be either the {@link DisplayContent} as the root* of the whole logical display, or a {@link DisplayAreaGroup} as the root of a partition of the* logical display.*/
class RootDisplayArea extends DisplayArea.Dimmable {

{@link DisplayArea}层次结构的根。它可以是作为整个逻辑显示的根的{@link DisplayContent},也可以是作为逻辑显示的分区的根的{@link DisplayAreaGroup}。
即:
DisplayContent,作为整个屏幕的DisplayArea层级结构根节点。
DisplayAreaGroup,作为屏幕上部分区域对应的DisplayArea层级结构的根节点

屏幕 —— DisplayContent


/*** Utility class for keeping track of the WindowStates and other pertinent contents of a* particular Display.*/
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {

用于跟踪特定显示器的WindowStates和其他相关内容的实用程序类,总而言之就是代表一个屏幕。
隶属于同一个DisplayContent的窗口将会被显示在同一个屏幕中。每一个DisplayContent都对应着唯一ID

DisplayAreaGroup

/** The root of a partition of the logical display. */
class DisplayAreaGroup extends RootDisplayArea {

逻辑显示分区的根

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/85080.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux下 时间戳的转化

Linux下一般用date 记录当前时间&#xff0c;尤其是我们需要保存测试log的时候&#xff0c;或者设计一个跑多长时间的脚本都需要时间戳。下面看一下平时最常用的几种写法 1 date “%Y-%m-%d %H:%M” 显示具体时间 2 修改时间 date -s 3 date %s :当前时间的时间戳 显示具体时…

去了字节跳动,才知道年薪40W的测试有这么多?

今年大环境不好&#xff0c;内卷的厉害&#xff0c;薪资待遇好的工作机会更是难得。最近脉脉职言区有一条讨论火了 哪家互联网公司薪资最‘厉害’&#xff1f; 下面的评论多为字节跳动&#xff0c;还炸出了很多年薪40W的测试工程师 我只想问一句&#xff0c;现在的测试都这么有…

Opencv-C++笔记 (16) : 几何变换 (图像的翻转(镜像),平移,旋转,仿射,透视变换)

文章目录 一、图像平移二、图像旋转2.1 求旋转矩阵2.2 求旋转后图像的尺寸2.3手工实现图像旋转2.4 opencv函数实现图像旋转 三、图像翻转3.1左右翻转3.2、上下翻转3.3 上下颠倒&#xff0c;左右相反 4、错切变换4.1 实现错切变换 5、仿射变换5.1 求解仿射变换5.2 OpenCV实现仿射…

Floyd算法

正如我们所知道的&#xff0c;Floyd算法用于求最短路径。Floyd算法可以说是Warshall算法的扩展&#xff0c;三个for循环就可以解决问题&#xff0c;所以它的时间复杂度为O(n^3)。 Floyd算法的基本思想如下&#xff1a;从任意节点A到任意节点B的最短路径不外乎2种可能&#xff…

SpringCloud实用篇2——Nacos配置管理 Feign远程调用 Gateway服务网关

目录 1 Nacos配置管理1.1 统一配置管理1.1.1 在nacos中添加配置文件1.1.2 从微服务拉取配置 1.2 配置热更新1.2.1 方式一1.2.2 方式二&#xff08;推荐&#xff09; 1.3.配置共享 2 搭建Nacos集群2.1 集群结构图2.2 搭建集群2.2.1 初始化数据库2.2.2 下载nacos2.2.3 配置Nacos2…

JavaSE 【类和对象】(3)(重点:内部类)

一、内部类 将一个类定义在另一个类或者一个方法的内部&#xff0c; 前者称为内部类&#xff0c;后者称为外部类 。内部类也是封装的一种体现 在外部类中&#xff0c;内部类定义位置与外部类成员所处的位置相同&#xff0c;因此称为成员内部类。 public class OutClass { c…

分布式异步任务处理组件(八)

分布式异步任务组件网络通信线程模型设计-- 大概说一下功能场景&#xff1a; 从节点和主节点建立连接&#xff0c;负责和主节点的网络IO通信&#xff0c;通信动作包括投票&#xff0c;心跳&#xff0c;举证等&#xff0c;步骤为读取主节点的信息&#xff0c;写入IO队列中&…

15.3.2 【Linux】系统的配置文件:/etc/crontab,/etc/cron.d/*

这个“ crontab -e ”是针对使用者的 cron 来设计的&#xff0c;如果是“系统的例行性任务”时&#xff0c; 该怎么办呢&#xff1f;是否还是需要以 crontab -e 来管理你的例行性工作调度呢&#xff1f;当然不需要&#xff0c;你只要编辑/etc/crontab 这个文件就可以。有一点需…

Prometheus技术文档-基本使用-配置文件全解!!!!!

简介&#xff1a; Prometheus是一个开源的系统监控和告警系统&#xff0c;由Google的BorgMon监控系统发展而来。它主要用于监控和度量各种时间序列数据&#xff0c;比如系统性能、网络延迟、应用程序错误等。Prometheus通过采集监控数据并存储在时间序列数据库中&#xff0c;…

【SpringBoot】日志是什么+基于lombok的日志输出

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE进阶 在我们日常的程序开发中&#xff0c;日志是程序的重要组成部分&#xff0c;想象⼀下&#xff0c;如果程序报错了&#xff0c;不让你打开控制台看⽇志&#xff0c;那么你能找到报错的原因吗…

【华秋推荐】新能源汽车中的T-BOX系统,你了解多少?

近几年&#xff0c;新能源汽车产业进入了加速发展的阶段。我国的新能源汽车产业&#xff0c;经过多年的持续努力&#xff0c;技术水平显著提升、产业体系日趋完善、企业竞争力大幅增强&#xff0c;呈现市场规模、发展质量“双提升”的良好局面。同时&#xff0c;通过国家多年来…

TypeScript 中【class类】与 【 接口 Interfaces】的联合搭配使用解读

导读&#xff1a; 前面章节&#xff0c;我们讲到过 接口&#xff08;Interface&#xff09;可以用于对「对象的形状&#xff08;Shape&#xff09;」进行描述。 本章节主要介绍接口的另一个用途&#xff0c;对类的一部分行为进行抽象。 类配合实现接口 实现&#xff08;impleme…

VR全景在建筑工程行业能起到哪些作用?

在建筑工程领域&#xff0c;数字化技术为行业的发展起到巨大的推动作用&#xff0c;虽然建筑施工行业主要是依赖于工人劳动力和施工设备&#xff0c;但是VR全景在该行业中方方面面都能应用&#xff0c;从设计建模到项目交付&#xff0c;帮助建筑师以及项目方更好的理解每个环节…

斗象科技-2023攻防演练必修高危漏洞集合下载(2个版本)

高危风险漏洞一直是企业网络安全防护的薄弱点&#xff0c;也成为HW 攻防演练期间 红队的重要突破口&#xff1b;每年HW 期间爆发了大量的高危风险漏洞成为红队突破网络 边界防护的一把利器&#xff0c;很多企业因为这些高危漏洞而导致整个防御体系被突破、 甚至靶标失守而遗憾出…

photoshop生成器引入到electron项目(electron与photoshop建立通信)

Photoshop引入了nodejs&#xff0c;在启动的时候&#xff0c;通过pipe调起nodejs运行时核心generator-builtin&#xff0c;通过KLVR机制与ps进行通信和交互&#xff0c;同时会加载用户编写的扩展。 这里记录一下引入时的踩坑过程 generator-core就是它的源码&#xff0c;elect…

Unity 编辑器资源导入处理函数 OnPreprocessAudio :深入解析与实用案例

Unity 编辑器资源导入处理函数 OnPreprocessAudio 用法 点击封面跳转下载页面 简介 在 Unity 中&#xff0c;资源导入是一个非常重要的环节&#xff0c;它决定了资源在项目中的使用方式和效果。Unity 提供了一系列的资源导入处理函数&#xff0c;其中之一就是 OnPreprocessAud…

Qt应用开发(基础篇)——拆分器窗口 QSplitter

一、前言 QSplitter继承于QFrame&#xff0c;QFrame继承于QWidget&#xff0c;是Qt的一个基础工具类。 框架类QFrame介绍 QSplitter拆分器&#xff0c;用户通过拖动子部件之间的边界来控制子部件的大小&#xff0c;在应用开发中数据分模块展示、图片展示等场景下使用。 二、QSp…

【金融量化】对企业进行估值的方法有哪些?

估值的方法有哪些&#xff1f; 如何对企业进行估值&#xff1f;有2个方法估算。 1 绝对估值法 它是一种定价模型&#xff0c;用于计算企业的内在价值。 比如说你可以根据公司近N年的现金流情况。借此去预测未来N年的现金流情况。所有的现金流数据都可以在年报上查询到。最后…

ip地址怎么改 手机ip地址怎么修改

IP地址是指互联网协议地址&#xff0c;是给互联网上的每台设备分配的一个唯一的标识符。改变IP地址是在一定的条件下&#xff0c;为了实现一些特定的目的而对设备的网络配置进行调整。下面将介绍一些常见的改变IP地址的方法。我们可以通过重启路由器或者计算机来更改IP地址。在…

那些年的Android开发经验记录

Android Studio 新版Logcat 从惊艳到放弃 AS总算更新了这个logcat了&#xff0c;原来的logcat真是使用起来贼难受&#xff0c;动不动过滤就失效&#xff0c;或者日志不打印&#xff0c;新版的logcat初步使用下来&#xff0c;那是贼舒服&#xff0c;先上一张界面图 一眼看…