c网站开发源代码/什么是营销型网站?
窗口中容器类介绍:
本节内容较多,建议结合前面的内容一起阅读:
1、addWindow的宏观概念
2、WindowManager#addView_1
3、WindowManager#addView_2
1)、WindowContainer:
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>{
……………………
}
WindowContainer的定义如上,可见其是一个容器,容器内的元素是自己或自己的子类(如:RootWindowContainer、DisplayContent、DisplayArea、DisplayArea.Tokens、TaskDisplayArea、Task、ActivityRecord、WindowToken、WindowState),而WindowContainer类继承自ConfigurationContainer类,该类也是一个容器类,其元素为自己或自己的子类。
其中有一些属性比较重要:mParent和mChildren,分别代表父节点和子节点。其中子节点是WindowList类型的,其排列顺序是依据其在z轴上的高度排列的,尾部的节点在z轴上最高最容易被用户看到。
2)、RootWindowContainer:
class RootWindowContainer extends WindowContainer<DisplayContent>implements DisplayManager.DisplayListener {
WindowContainer的根容器,可通过该节点遍历到窗口树上的任意窗口。他的mChildren继承自WindowContainer,所以该List的元素为DisplayContent。
3)、DisplayContent:
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {
对应显示屏幕的概念,一个屏幕对应一个DisplayContent。一般情况下都是只有一个。在同一个DisplayContent中的窗口都会显示在同一个屏幕内。
4)、WindowToken:
class WindowToken extends WindowContainer<WindowState> {
WindowToken类是WindowState的容器,WindowState之前说过,在WMS中代表了一个窗口。
5)、ActivityRecord:
final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
该类继承自WindowToken,所以也是WindowState类的容器。
6)、WindowState:
class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState,InsetsControlTarget, InputTarget {
其实WindowState也可以作为其他WindowState的容器;
7)、WallpaperWindowToken:
class WallpaperWindowToken extends WindowToken {
该类同样继承自WindowToken;
对以上4)-7)进行统一分析,所有的窗口分三大类:系统窗口、应用窗口、其他窗口;其中系统窗口在最上层,应用窗口次之,而系统窗口的容器则为WindowToken,应用窗口为ActivityRecord。而App以下的窗口,父容器就为WallpaperWindowToken。
8)、DisplayArea.Tokens:
是WindowToken的父容器,同时会在其中对WindowToken进行排序;
public static class Tokens extends DisplayArea<WindowToken> {
private final Comparator<WindowToken> mWindowComparator =Comparator.comparingInt(WindowToken::getWindowLayerFromType);//这就是排序算法的核心。
}
排序算法触发的前提就是addChild函数,和前一节说的一样,找到addChild函数:
void addChild(WindowToken token) {addChild(token, mWindowComparator);
}
这里可以看到在addChild的时候,通过mWindowComparator为WindowToken确认顺序,而mWindowComparator的初始化是通过WindowToken.java中的getWindowLayerFromType方法作为比较器的。最后的方法实现在WindowManagerPolicy.java中的getWindowLayerFromTypeLw()方法。这里在addWindow的宏观概念一文中有讲到,主要就是对比了窗口的类型,如果是应用窗口则直接返回2,如果是wallpaper窗口,直接返回1(在最底层);然后再根据窗口的类型返回其排序的权重,根据权重再决定该窗口在子窗口中该插入到哪个位置。其中这里的type是在WindowToken中的一个属性:从注释看就是WindowManager类中的LayoutParams属性,这个属性会在窗口初始化时确定。
/** The type of window this token is for, as per {@link WindowManager.LayoutParams} */
final int windowType;
9)、Task:
ActivityRecord的容器,作为应用窗口的容器,ActivityRecord也是需要容器的。
class Task extends TaskFragment {
从定义可见Task是继承自TaskFragment的一个类。而TaskFragment则也是继承自WindowContainer的类。
class TaskFragment extends WindowContainer {
Task可以是Task的容器,也可以是ActivityRecord的容器,最形象的理解就是多任务界面的一个窗口就是一个Task。TaskFragment这个类型我了解不多,只知道和平行视界相关。平行视界中两个Activity需要同时显示,Task实现不了这个功能,所以再Task和ActivityRecord之间加入了TaskFragment。而一般情况下因为TaskFragment是Task的父类,所以大家都会通过TaskFragment创建对象,但是最终创建的还是Task类型的对象
这里的排序的话比较简单:老规矩找到addchild方法。
void addChild(WindowContainer child, int index) {index = getAdjustedChildPosition(child, index);super.addChild(child, index);ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addChild: %s at top.", this);// A rootable task that is now being added to be the child of an organized task. Making// sure the root task references is keep updated.if (mTaskOrganizer != null && mCreatedByOrganizer && child.asTask() != null) {getDisplayArea().addRootTaskReferenceIfNeeded((Task) child);}// Make sure the list of display UID allowlists is updated// now that this record is in a new task.mRootWindowContainer.updateUIDsPresentOnDisplay();// Only pass minimum dimensions for pure TaskFragment. Task's minimum dimensions must be// passed from Task constructor.下面应该就是平行视界这类相关的操作了final TaskFragment childTaskFrag = child.asTaskFragment();if (childTaskFrag != null && childTaskFrag.asTask() == null) {childTaskFrag.setMinDimensions(mMinWidth, mMinHeight);// The starting window should keep covering its task when a pure TaskFragment is added// because its bounds may not fill the task.final ActivityRecord top = getTopMostActivity();if (top != null) {top.associateStartingWindowWithTaskIfNeeded();}}
}
这个方法比较直接,直接通过index指定了位置。虽然指定了位置,但是程序中还是要对其进行调整的。
private int getAdjustedChildPosition(WindowContainer wc, int suggestedPosition) {final boolean canShowChild = wc.showToCurrentUser();final int size = mChildren.size();// Figure-out min/max possible position depending on if child can show for current user.int minPosition = (canShowChild) ? computeMinUserPosition(0, size) : 0;int maxPosition = minPosition;if (size > 0) {maxPosition = (canShowChild) ? size - 1 : computeMaxUserPosition(size - 1);}// Factor in always-on-top children in max possible position.if (!wc.isAlwaysOnTop()) {// We want to place all non-always-on-top containers below always-on-top ones.while (maxPosition > minPosition) {if (!mChildren.get(maxPosition).isAlwaysOnTop()) break;--maxPosition;}}// preserve POSITION_BOTTOM/POSITION_TOP positions if they are still valid.if (suggestedPosition == POSITION_BOTTOM && minPosition == 0) {return POSITION_BOTTOM;} else if (suggestedPosition == POSITION_TOP && maxPosition >= (size - 1)) {return POSITION_TOP;}// Increase the maxPosition because children size will grow once wc is added.if (!hasChild(wc)) {++maxPosition;}// Reset position based on minimum/maximum possible positions.return Math.min(Math.max(suggestedPosition, minPosition), maxPosition);
}
这里其实就是根据最大最小值和指定的值进行对比然后修正一下。
不过还有另一个形式的addChild算法:
void addChild(WindowContainer child, final boolean toTop, boolean showForAllUsers) {Task task = child.asTask();//这里如果child是task则返回一个值,否则返回null。try {if (task != null) {task.setForceShowForAllUsers(showForAllUsers);}// We only want to move the parents to the parents if we are creating this task at the// top of its root task.addChild(child, toTop ? MAX_VALUE : 0, toTop /*moveParents*/);} finally {if (task != null) {task.setForceShowForAllUsers(false);}}
}
这个算法参数都不同了,有三个参数,这里第一步直接判断子元素是不是task类型。如果是的话,就执行setForceShowForAllUsers该方法,但是这里也没啥,就是对mForceShowForAllUsers进行赋值,然后就是对其进行比较器为null的排序,这里就不重复讲了,比较的过程在WindowContainer.java中的protected void addChild(E child, Comparator comparator) 该方法中。
10)、TaskDisplayArea:
Task或者TaskDisplayArea的容器。继承自DisplayArea类。代表的是屏幕上一块专门用来存放app窗口的区域。其父容器是DisplayContent。
final class TaskDisplayArea extends DisplayArea<WindowContainer> {
这个类对其中元素排序的方法依然可以通过addChild方法去查看,
void addChild(WindowContainer child, int position) {if (child.asTaskDisplayArea() != null) {if (DEBUG_ROOT_TASK) {Slog.d(TAG_WM, "Set TaskDisplayArea=" + child + " on taskDisplayArea=" + this);}super.addChild(child, position);} else if (child.asTask() != null) {addChildTask(child.asTask(), position);} else {throw new IllegalArgumentException("TaskDisplayArea can only add Task and TaskDisplayArea, but found "+ child);}
}
其对于两个子类的元素有着不同的排序方法。第一种就是直接调用WindowContainer.java中的addChild(E child, int index)方法,直接在指定位置添加。
第二个的话就是如果元素是task类的话其实和上面也差不多,就是通过当前已有的一些子类对指定的位置进行一些修正。
11)、DisplayArea:
该类用于将WindowContainer分组到DisplayContent下方的容器。DisplayArea是被DisplayAreaPolicy管理的,能够复写Configuration和被绑定到leash上,并且可以嵌套DisplayArea,该类有三种风格:
BELOW_TASKS:只能包含位于任务下方的BELLOW_TASK显示区域和WindowToken。
ABOVE_TASKS:只能包含位于任务上方的ABOVE_TASK显示区域和WindowToken。
ANY:可以包含任何类型的DisplayArea,以及任何类型的WindowToken或Task容器。
12)、RootDisplayArea:
DisplayArea的根节点。根据注释来看:从等级制度上是DisplayArea的根节点。同时也可以是 逻辑屏幕上DisplayContent的根节点,或者逻辑屏幕上一个群组DisplayAreaGroup的根节点。
/*** 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 {
所以这里将屏幕上的窗口分为两个逻辑,一个是等级制度,一个是物理屏幕。
13)、DisplayAreaGroup:
继承自RootDisplayArea,可以理解为一个集群,一个DisplayArea和DisplayContent之间的一个集群。 DisplayContent是整个屏幕上DisplayArea的根节点,但是一部分DisplayArea也可以挂载在DisplayAreaGroup上 。
/** The root of a partition of the logical display. */
class DisplayAreaGroup extends RootDisplayArea {
14)、另外还有一个容器ImeContainer:
这是输入法相关的,我暂时没了解,看定义大概能知道也是一类WindowToken的容器。
private static class ImeContainer extends DisplayArea.Tokens {
综上最后得到一个关系图:其中我将一个层级的都用同一个颜色标注出来。
然后再通过类图对其中涉及到的类进行归类。
相关文章:

WindowManager相关容器类
窗口中容器类介绍: 本节内容较多,建议结合前面的内容一起阅读: 1、addWindow的宏观概念 2、WindowManager#addView_1 3、WindowManager#addView_2 1)、WindowContainer: class WindowContainer<E extends WindowC…...

零售行业运营有哪些业务场景?详解各业务场景的分析指标和维度
在当今这个数字化迅速发展的时代,零售行业正经历着前所未有的变革。传统的零售模式正在被新兴的技术和创新的业务场景所颠覆,消费者的需求和购物习惯也在不断地演变。零售行业的运营,作为连接消费者、产品和市场的关键环节,对于零…...

无锡哲讯携手SAP,赋能装备制造业数字化转型
在当今快速发展的工业4.0时代,装备制造业作为国民经济的重要支柱,正面临着前所未有的机遇与挑战。无锡哲讯智能科技有限公司凭借其深厚的行业经验和专业的SAP实施能力,为装备制造业提供全面的数字化解决方案,助力企业实现智能化、…...

TPM仿真环境搭建
文章目录 背景及注意事项一、CMake二、m4三、GNU MP Library四、TPM_Emulator五、TSS协议栈(trousers-0.3.14.tar.gz)六、 tpm-tools七、查看是否安装成功八、测试 TPM环境(需要开三个终端分别运行)8.1 启动TPM (第一个…...

提高篇(五):使用Processing创作互动艺术:从灵感到实现
提高篇(五):使用Processing创作互动艺术:从灵感到实现 引言 互动艺术将观众从被动的观察者转变为主动参与者,通过创意编程和技术手段,让艺术品具备感知和回应的能力。Processing作为一种强大的创意编程工具,提供了丰富的功能和灵活的编程环境,帮助艺术家和设计师实现他…...

华为od-C卷100分题目-3用连续自然数之和来表达整数
华为od-C卷100分题目-3用连续自然数之和来表达整数 题目描述 一个整数可以由连续的自然数之和来表示给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式 输入描述 一个目标整数T(1<T<1000) 输出描述 该整数的所有表达…...

Chrome 自动执行 JS 脚本 | Tampermonkey 插件
文章目录 第 1 步:安装插件 Tampermonkey第 2 步:固定到工具栏第 3 步:在网站上启用 Tampermonkey第 4 步:查看效果第 5 步:调试 JS 代码😂 背景:有个网站,每次进去都要点 3 次才能把相关页面展开。而且,页面经常会自己刷新,导致展开的页面又收回去了。【这一天天的…...

ffmplay 源码解读
stream_open 讲解 // 定义一个静态函数用于初始化并返回VideoState结构体指针,用于管理播放状态 static VideoState* stream_open(const char* filename, AVInputFormat* iformat) {VideoState* is; // 创建VideoState结构体指针// 分配内存并初始化VideoState结构…...

java web如何调用py脚本文件
Controller public class IndexController {RequestMapping("/pythonTest")ResponseBodypublic String pythonTest(){// 假设你的Python脚本名为script.pyString pythonScriptPath "D:\\project\\c1\\hello.py";ProcessBuilder processBuilder new Proce…...

K8s:无状态
无状态服务 无状态服务是指服务的实例之间没有持久化状态,每个实例都是相同的,可以互换使用。 调度器 ReplicationController 简称 RC是 Kubernetes 早期版本中用来确保 Pod 副本始终运行的 API 对象。它通过监控 Pod 副本的数量,确保任何…...

Docker 入门篇(九)-- 使用 Maven 插件 构建 Docker 镜像
在这篇教程中,我们将学习如何使用 Maven 插件为 Spring Boot 应用构建 Docker 镜像。我们将使用 spring-boot-maven-plugin 和 dockerfile-maven-plugin 这两个插件。 一、前提条件 已安装 Docker。已安装 JDK 8 或以上版本。已安装 Maven。 二 创建一个 Spring …...

网络协议三
数据中心 一、DNS 现在网站的数目非常多,常用的网站就有二三十个,如果全部用 IP 地址进行访问,恐怕很难记住 根 DNS 服务器 :返回顶级域 DNS 服务器的 IP 地址 顶级域 DNS 服务器:返回权威 DNS 服务器的 IP 地址 …...

LeetCode LRU缓存
题目描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,…...

Parallels Desktop for Mac 19.4.0更新了哪些内容?有什么改进?
带来了重新设计的共享 Mac 文件夹版本,这些文件夹现在是符号链接,像指针一样指向您的 Mac 文件夹中的文件,同时仍然显示在 Windows 的本地磁盘上。 修复了由于共享文件夹问题导致 NinjaTrader 无法正常启动的问题。 修复了由于共享文件夹问…...

Python 将CSV文件转为PDF文件
CSV文件通常用于存储大量的数据,而PDF文件则是一种通用的文档格式,便于与他人共享和打印。将CSV文件转换成PDF文件可以帮助我们更好地管理和展示数据。本文将介绍如何通过Python编程将CSV文件导出为PDF文件。 Python Excel库安装及介绍 在 Python 中&am…...

4_XMR交易过程
XMR交易过程 参考文档 书: 《精通门罗币 : 私密交易的未来》(Mastering Monero) 书中的代码示例: 《精通门罗币 : 私密交易的未来》深入探究门罗币与密码学门罗币的环签名分析官方介绍视频 1.隐匿地址 Stealth Address_Monero官方介绍视频2.环签名 Ring Signature_Monero官方…...

02_共享锁和排他锁
共享锁和排他锁 文章目录 共享锁和排他锁简介共享锁(Shared Lock, S Lock)简介原理使用方式加锁流程使用场景 排他锁(Exclusive Lock, X Lock)简介原理使用方式加锁流程使用场景 对比注意事项结论 简介 MySQL 中的共享锁和排他锁…...

Ubuntu的启动过程
尽管通常情况下Ubuntu的启动并不需要用户过多地参与,但是Ubuntu系统的启动本身是一个非常复杂的过程。在这个过程中,有硬件的检测、系统内核的准备以及各种系统服务的启动等。作为系统管理员,需要深入了解其中所经历的阶段,才能在…...

c# 下 ScintillaNET 显示XML信息并折叠节点
winform下显示XML信息(非WPF) 之前使用的是FastColoredTextBox,github地址如下: https://github.com/PavelTorgashov/FastColoredTextBox 但是有个问题,它支持中文,wordwraptrue,自动换行时&…...

什么叫防御式编程
防御式编程是一种编程策略,主要目的是提高代码的健壮性和可靠性。它假设任何错误都可能发生,并且在设计和编写代码时采取预防措施以防止这些错误导致程序崩溃或产生错误结果。 以下是一些防御式编程的常见实践: 输入验证:总是验证…...

前端优化之图片压缩——tinyPNG
今天前端前辈新介绍的一个压缩图片的工具——tinyPNG,地址:TinyPNG – Compress WebP, PNG and JPEG images intelligently可以将图片压缩,进行优化。 一、使用方法——手动压缩 将超过200kb的图片拖到我标注的红框框里,拖到这里…...

Springboot集成Quartz
Quartz简介 Job 表示一个工作,要执行的具体业务内容。 JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。 Trigger 代表一个调度参数的配置…...

Android面试题之Kotlin Jetpack组件LifecycleScope
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点 在Kotlin中,LifecycleScope是Android Jetpack架构组件的一部分,主要用于简化与生命周期相关的协程管理。 它属于android…...

MySQL深分页优化
MySQL中的深分页问题通常是指当我们通过LIMIT语句查询数据,尤其是在翻到较后面的页码时,性能会急剧下降。例如,查询第1000页的数据,每页10条,系统需要跳过前9990条数据,然后才能获取到所需的记录࿰…...

问题:律师会见委托人的方式包括团体会见和( )。 #职场发展#笔记#学习方法
问题:律师会见委托人的方式包括团体会见和( )。 参考答案如图所示...

Spring Boot中整合Jasypt 使用自定义注解+AOP实现敏感字段的加解密
😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…...

pytorch中的维度变换操作性质大总结:view, reshape, transpose, permute
在深度学习中,张量的维度变换是很重要的操作。在pytorch中,有四个用于维度变换的函数,view, reshape, transpose, permute。其中view, reshape都用于改变张量的形状,transpose, permute都用于重新排列张量的维度,但它们…...

LeetCode刷题 | Day 4 分割等和子集(Partition Equal Subset Sum)自底向上动态规划
LeetCode刷题 | Day 4 分割等和子集(Partition Equal Subset Sum)自底向上动态规划 文章目录 LeetCode刷题 | Day 4 分割等和子集(Partition Equal Subset Sum)自底向上动态规划前言一、题目概述二、解题方法2.1 一维表格的自底向上动态规划2.1.1 思路讲解2.1.2 伪代码 + 逐…...

基于工业互联网打造敏捷供应链的实现方式:创新路径与实践应用
引言 工业互联网和敏捷供应链是当今制造业发展中的两个重要概念。工业互联网以数字化、网络化和智能化为核心,致力于将传统工业生产与互联网技术相融合,从而实现生产过程的高效、智能和灵活。而敏捷供应链则强调快速响应市场需求、灵活调整生产和供应计划…...

碳化硅柱式膜的广泛应用
碳化硅柱式膜是一种高性能的过滤材料,以其独特的性质和广泛的应用领域在现代工业中占据着重要地位。以下是对碳化硅柱式膜的详细介绍: 一、基本概述 碳化硅柱式膜是以碳化硅超滤膜为过滤单元构成的,其过滤精度高达0.1微米。这种膜材料具有耐化…...