当前位置: 首页 > news >正文

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

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。

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 {

逻辑显示分区的根

相关文章:

Android T 窗口层级相关的类(更新中)

窗口在App端是以PhoneWindow的形式存在&#xff0c;承载了一个Activity的View层级结构。这里我们探讨一下WMS端窗口的形式。 可以通过adb shell dumpsys activity containers 来看窗口显示的层级 窗口容器类 —— WindowContainer类 /*** Defines common functionality for c…...

【云原生】深入掌握k8s中Pod和生命周期

个人主页&#xff1a;征服bug-CSDN博客 kubernetes专栏&#xff1a;kubernetes_征服bug的博客-CSDN博客 目录 1 什么是 Pod 2 Pod 基本操作 3 Pod 运行多个容器 4 Pod 的 Labels(标签) 5 Pod 的生命周期 1 什么是 Pod 摘取官网: Pod | Kubernetes 1.1 简介 Pod 是可以在 …...

openKylin+KingbaseES+Nginx安装

openKylin开放麒麟开启ssh 一、查看ssh服务是否开启。 终端输入命令&#xff1a;sudo ps -e |grep ssh &#xff0c;只显示如下内容则证明未安装ssh服务。 2127 ? 00:00:00 ssh-agent若显示如下内容则证明ssh服务已开启。 1657 ? 00:00:00 ssh-agent 2349 ?…...

lc1.两数之和

暴力解法&#xff1a;两个for循环&#xff0c;寻找和为target的两个数的索引 时间复杂度&#xff1a;O(n2) 空间复杂度&#xff1a;O(1) 哈希表&#xff1a;遍历数组&#xff0c;将nums数组的数和索引分别存储在map的key和value中&#xff0c;一边遍历&#xff0c;一边寻找是…...

c# 初始化列表,并给列表里面所有的元素进行初始化

Enumerable.Repeat 方法是用于生成一个包含指定元素重复若干次的序列。它接受两个参数&#xff0c;第一个参数是要重复的元素&#xff0c;第二个参数是重复次数。 下面是 Enumerable.Repeat 方法的用法和示例&#xff1a; using System; using System.Collections.Generic; u…...

Java笔记(三十):MySQL(上)-- 数据库、MySQL常用数据类型、DDL、DML、多表设计

一、数据库 0、MySQL安装&#xff0c;IDEA配置MySQL 用MySQL installer for windows&#xff08;msi&#xff09;MySQL默认安装位置&#xff1a;C:\Program Files\MySQL\MySQL Server 8.0配置环境变量使用前先确保启动了mysql服务my.ini位置&#xff1a;C:\ProgramData\MySQL…...

SQL笔记-正态分布函数(二)

在Oracle数据库中&#xff0c;并没有直接提供计算正态分布函数&#xff08;累积分布函数&#xff09;的内置函数。不过&#xff0c;你可以使用PL/SQL编程语言来实现一个自定义的正态分布函数。下面是一个简单的示例&#xff1a; CREATE OR REPLACE FUNCTION normdist(x NUMBER…...

【LeetCode】数据结构题解(12)[用栈实现队列]

用栈实现队列 &#x1f609; 1.题目来源&#x1f440;2.题目描述&#x1f914;3.解题思路&#x1f973;4.代码展示 所属专栏&#xff1a;玩转数据结构题型❤️ &#x1f680; >博主首页&#xff1a;初阳785❤️ &#x1f680; >代码托管&#xff1a;chuyang785❤️ &…...

嵌入式Linux下LVGL的移植与配置

一.sdk源码下载路径 1.官方源码下载路径如下: ​​​​​​ https://github.com/lvgl/lvgl git下载方式 git clone https://github.com/lvgl/lvgl.git 2.个人移植好的源码8.2版本下载路径: 链接&#xff1a;https://pan.baidu.com/s/1jyqIennsQpv-RB4RyKvZyg?pwdc68e 提取…...

leetcode每日一练-第70题-爬楼梯

一、思路 动态规划 二、解题方法 使用一个动态规划数组 dp 来记录到达每个台阶的不同方法数。初始情况下&#xff0c;当台阶数为 1 时&#xff0c;方法数为 1&#xff0c;当台阶数为 2 时&#xff0c;方法数为 2。然后&#xff0c;我们从第 3 阶开始逐步计算每一阶的方法数&…...

设备使用RTMP推流到安防监控EasyCVR视频汇聚平台,为何只有FLV格式无法播放?

TSINGSEE青犀视频安防监控视频汇聚平台EasyCVR基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能分析等功能。 智能视频监控平台EasyCVR可…...

arcgis宗地或者地块四至权利人信息提取教程

ARCGIS怎样将图斑四邻的名称及方位加入其属性表 以前曾发表过一篇《 如何把相邻图斑的属性添加在某个字段中》的个人心得,有些会员提出了进一步的要求,不但要相邻图斑的名称,还要求有方位,下面讲一下自己的做法。 基本思路是:连接相邻图斑质心,根据连线的角度确定相邻图斑…...

乐鑫首创|使用 ESP RainMaker® 私有云定制 Matter 生态

ESP RainMaker 是乐鑫的 AIoT 云平台&#xff0c;支持客户自主部署私有物联网云&#xff0c;从而全面掌握数据所有权和管理权&#xff0c;实现定制功能与服务。ESP RainMaker 云后端采用 AWS 无服务器架构&#xff0c;拥有开源的 iOS 和 Android 移动端 APP、第三方语音助手集成…...

【算法|数组】快慢指针

算法|数组——快慢指针 引入 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你…...

C++字符串:使用 std::string

C字符串&#xff1a;使用 std::string 初始化方法一 std::string 变量名称 { “字符串”}&#xff1b; std::string str { " 这是一个字符串" }&#xff1b;std::cout << str; std::cin >> str;初始化方法二 std::string 变量名称 { “字符串”&#x…...

目前Java后端就业前景怎么样?

前言 并不乐观&#xff0c;看看现在的就业形式就知道了&#xff0c;基本上是僧多粥少的情况&#xff0c;你可能会看到很多编程语言排行榜或者流行榜中Java的排名很高&#xff0c;如同下面这种&#xff1a; 看排名确实可以粗略的得知语言当下的流行度、使用率&#xff0c;但是它…...

C语言基础(持续更新)

常用函数 strrchr 描述 C 库函数 char *strrchr(const char *str, int c) 在参数 str 所指向的字符串中搜索最后一次出现字符 c&#xff08;一个无符号字符&#xff09;的位置。测试代码 #include "stdio.h" #include "string.h"int main() {printf(&q…...

从源码层面深度剖析Spring循环依赖 | 京东云技术团队

以下举例皆针对单例模式讨论 图解参考 https://www.processon.com/view/link/60e3b0ae0e3e74200e2478ce 1、Spring 如何创建Bean&#xff1f; 对于单例Bean来说&#xff0c;在Spring容器整个生命周期内&#xff0c;有且只有一个对象。 Spring 在创建 Bean 过程中&#xff0…...

Distance 2023牛客暑期多校训练营6 B

登录—专业IT笔试面试备考平台_牛客网 题目大意&#xff1a;给出两个长度为n的数组a&#xff0c;b&#xff0c;每次操作可以令一个数1&#xff0c;将a的一个子集A变成和b的一个子集B变成完全相同需要的最少操作数为C(A,B)&#xff0c;求对于a的所有子集对所有b的子集的C(A,B)的…...

【Pandas】学习笔记之groupby()、agg()、transform()

在数据分析过程中经常需要对数据集进行分组&#xff0c;并且统计均值&#xff0c;最大值等等。那么 groupby() 的学习就十分有必要了 groupby(): 分组 官方文档&#xff1a; DataFrame.groupby(byNone, axis0, levelNone, as_indexTrue, sortTrue, group_keysTrue, observedF…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章&#xff0c;抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法&#xff0c;已经有很多的工作和这个任务相关。这两年 diffusion 模型很火&#xff0c;大家又开始用 diffusion 模型做各种 CV 任务了&am…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...