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

news2024/12/27 12:02:03

窗口在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.coloradmin.cn/o/860614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中睿天下入选河南省网信系统2023年度网络安全技术支撑单位

近日&#xff0c;河南省委网信办发布了“河南省网信系统2023年度网络安全技术支撑单位名单”&#xff0c;中睿天下凭借出色的网络安全技术能力和优势成功入选。 本次遴选由河南省委网信办会同国家计算机网络与信息安全管理中心河南分中心&#xff08;以下简称安全中心河南分中心…

MySQL高级-存储引擎+存储过程+索引(详解01)

目录 1.mysql体系结构 2.存储引擎 2.1.存储引擎概述 2.2.1.InnoDB 2.2.2.MyISAM 2.2.3.存储引擎选择 3.存储过程 3.1.存储过程和函数概述 3.2.创建存储过程 3.3.调用存储过程 3.4.查看存储过程 3.5.删除存储过程 3.6.语法 3.6.1.变量 3.6.2.if条件判断 3.6.3.…

【STM32】利用CubeMX对FreeRTOS用按键控制任务

对于FreeRTOS中的操作&#xff0c;最常用的就是创建、删除、暂停和恢复任务。 此次实验目标&#xff1a; 1.创建任务一&#xff1a;LED1每间隔1秒闪烁一次&#xff0c;并通过串口打印 2.创建任务二&#xff1a;LED2每间隔0.5秒闪烁一次&#xff0c;并通过串口打印 3.创建任…

[oeasy]python0083_[趣味拓展]字体样式_正常_加亮_变暗_控制序列

字体样式 回忆上次内容 上次了解了 一个新的转义模式 \033 逃逸控制字符 esc esc 让输出 退出 标准输出流进行 控制信息的设置 可以 清屏也可以 设置光标输出的位置 还能做什么呢&#xff1f; 可以 设置 字符的颜色吗&#xff1f;&#xff1f;&#xff1f;&#x1f914; 查…

Vue3 组件基础简单应用

去官网学习→组件基础 | Vue.js 运行示例&#xff1a; 自定义组件 代码&#xff1a; MyComponent.vue <template><h2>MyComponent.vue 组件</h2> </template><script>// 导出export default{name:"MyComponent"} </script><…

Java一般用于postgis空间数据库通用的增删查改sql命令

目录 1 增加 2 删除 3 查询 4 更新 "public"."JGSQGW_Geo"为某模式下得表 一般postgrel有这样的设计模式 1 增加 #前端绘制出的数据插入 INSERT INTO "public"."JGSQGW_Geo" ( "geom","gridone","gridon…

prometheus告警发送组件部署

一、前言 要实现Prometheus的告警发送需要通过alertmanager组件&#xff0c;当prometheus触发告警策略时&#xff0c;会将告警信息发送给alertmanager&#xff0c;然后alertmanager根据配置的策略发送到邮件或者钉钉中&#xff0c;发送到钉钉需要安装额外的prometheus-webhook…

API HOOK技术在MFC程序破解过程中的应用

更新&#xff0c;修改了一下typora的上传脚本&#xff0c;把图片全部上传到看雪上了 本文已于2023-08-02首发于个人博客 图片加载不出来&#xff0c;放了一个PDF版本在附件里 文中有几张图片是动图&#xff0c;如果不会动&#xff0c;可以去我的个人博客看 最近破解了一个M…

Kettle lookup 流查询组件关键词匹配应用案例

Kettle 流查询组件lookup应用案例详解 需求说明 通过对初始的文本文件按照引用表匹配&#xff0c;过滤后的记录输入到表中。 解决方案 Step1&#xff1a;拖动表输入&#xff0c;配置要查询字段及表 Step2&#xff1a;文件文件输入&#xff0c;指定文本文件路径及字段名称、字…

DB-Engines 排名调查

目录 一、理论 1.DB-Engines排名 一、理论 1.DB-Engines排名 &#xff08;1&#xff09;概念 DB-Engines排名是数据库领域的流行度榜单&#xff0c;它对全球范围内的419款数据库&#xff08;截至2023年8月&#xff09;进行排名&#xff0c;每月更新一次&#xff0c;排名越靠…

简单程度与自负是否相关?探索STM32的学习价值

事实上&#xff0c;无论STM32是否简单并不重要&#xff0c;更重要的是我们能通过学习STM32获得什么。通过STM32&#xff0c;我们可以学习到许多知识&#xff1a;如果我们制作一个键盘或鼠标&#xff0c;我们可以学习USB协议。如果我们制作一个联网设备&#xff0c;我们需要学习…

想知道有关再营销活动的一切?看这一篇文章就够了

有没有想过怎样充分利用过去的流量&#xff1f;假设您开展了一场精彩的营销活动&#xff0c;并吸引了大量用户访问您的网站。但他们大部分都没有像你期望的那样完成交易。推出再营销活动&#xff0c;这就是您向那些已经接触过您的营销活动但尚未采取任何具体行动的人进行营销的…

代码随想录算法训练营第十四天|对树的初步认识

二叉树种类 在我们解题过程中二叉树有两种主要的形式&#xff1a;满二叉树和完全二叉树。 满二叉树 满二叉树&#xff1a;如果一棵二叉树只有度为0的结点和度为2的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。 这棵二叉树为满二叉树&…

性能测评:腾讯云轻量应用服务器_CPU内存带宽流量

腾讯云轻量应用服务器性能如何&#xff1f;轻量服务器CPU内存带宽配置高&#xff0c;CPU采用什么型号主频多少&#xff1f;轻量应用服务器会不会比云服务器CVM性能差&#xff1f;腾讯云服务器网详解CPU型号主频、内存、公网带宽和系统盘存储多维对比&#xff0c;相对于CVM云服务…

机器人CPP编程基础-03变量类型Variables Types

机器人CPP编程基础-02变量Variables 全文AI生成。 C #include<iostream>using namespace std;main() {int a10,b35; // 4 bytescout<<"Value of a : "<<a<<" Address of a : "<<&a <<endl;cout<<"Val…

排序的介绍

排序算法介绍 排序是计算机内经常进行的一种操作&#xff0c;其目的是将一组“无序”的记录序列调整为“有序”的记录序列 粗暴理解 将杂乱无章的数据元素&#xff0c;通过一定的方法按照关键字顺序排列的过程叫做排序 排序分内部排序和外部排序&#xff0c;若整个排序过程不需…

4路光栅尺磁栅尺编码器5MHz高速差分信号转Modbus TCP网络模块 YL97

特点&#xff1a; ● 光栅尺磁栅尺解码转换成标准Modbus TCP协议 ● 光栅尺5V差分信号直接输入&#xff0c;4倍频计数 ● 模块可以输出5V的电源给光栅尺供电 ● 高速光栅尺磁栅尺计数&#xff0c;频率可达5MHz ● 支持4个光栅尺同时计数&#xff0c;可识别正反转 ● 可网…

JD商品详情页面+关键词搜索商品列表API接口数据,详情页面数据返回值说明

作为一个工作助手&#xff0c;我无法直接为您提供实时的京东商品详情。您可以通过访问京东官方网站或使用API接口来查看商品的详细信息。每个商品的详情页面通常会包括以下内容&#xff1a; 1. 商品标题&#xff1a;商品的名称和简要描述。 2. 价格信息&#xff1a;包括原价、…

常见问题03:SpringBoot项目启动初始化数据(执行sql文件)

1、类ResourceDatabasePopulator介绍 使用外部资源中定义的 SQL 脚本填充、初始化或清理数据库。 调用addScript(org.springframework.core.io.Resource)以添加单个 SQL 脚本位置。调用addScripts(org.springframework.core.io.Resource…)以添加多个 SQL 脚本位置。请参阅此类…

通讯协议035——全网独有的OPC HDA知识一之聚合(四)平均值

本文简单介绍OPC HDA规范的基本概念&#xff0c;更多通信资源请登录网信智汇(wangxinzhihui.com)。 本节旨在详细说明HDA聚合的要求和性能。其目的是使HDA聚合标准化&#xff0c;以便HDA客户端能够可靠地预测聚合计算的结果并理解其含义。如果用户需要聚合中的自定义功能&…