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

【Android】Window和WindowManager

文章目录

    • 理解Window和WindowManager
      • Window和WindowManager
      • Window的内部机制
        • Window的添加过程
        • Window的删除过程
        • Window的更新过程
    • Window的创建过程
      • Activity的Window创建过程
      • Dialog的Window创建过程
      • Toast的Window创建过程

理解Window和WindowManager

Window是一个抽象类,它的具体实现是PhoneWindow。WindowManager是外界访问Window的入口,Window的具体实现位于WindowManagerService中,WindowManager和WindowManagerService的交互是一个IPC过程。Android中所有的视图都是通过Window来呈现的,不管是Activity、Dialog还是Toast,它们的视图实际上都是附加在Window上的,因此Window实际是View的直接管理者。

Window和WindowManager

为了分析Window的工作机制,先通过代码了解如何使用WindowManager添加一个Window,下面一段代码将一个Button添加到屏幕坐标为(100, 300)的位置上

mFloatingButton = new Button(this);
mFloatingButton.setText("test button");
mLayoutParams = new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0, PixelFormat.TRANSPARENT);//0,0 分别是type和flags参数
mLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_SHOW_WHEN_LOCKED;
mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR;
mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
mLayoutParams.x = 100;
mLayoutParams.y = 300;
mFloatingButton.setOnTouchListener(this);
mWindowManager.addView(mFloatingButton, mLayoutParams);

Flags参数表示Window的属性,以下列举常用的选项:

  • FLAG_NOT_FOCUSABLE:表示Window不需要获取焦点,也不需要接收各种输入事件,此标记会同时启动FLAG_NOT_TOUCH_MODEL,最终事件会传递给下层的具有焦点的Window
  • FLAG_NOT_TOUCH_MODAL:在此模式下,系统会将当前Window区域以外的单击事件传递给底层的Window,当前Window区域以内的单击事件则自己处理。这个标记很重要,一般来说都需要开启此标记,否则其他Window将无法收到单击事件。
  • FLAG_SHOW_WHEN_LOCKED:开启此模式可以让显示在锁屏的界面

Type参数表示Window的类型,Window有三种类型,分别是应用Window子Window系统Window

  • 应用类Window对应着一个Activity。
  • 子Window不能单独存在,它需要附属在特定的父Window之中,比如常见的一些Dialog就是一个子Window。
  • 系统Window是需要声明权限才能创建的Window,比如Toast和系统状态栏这些都是系统Window。

Window是分层的,每个Window都有对应的z-ordered,层级最大的会覆盖在层级小的Window上面,这和HTML中的z-index的概念是完全一致的。在三类Window中,应用Window的层级范围是199,子Window的层级范围是10001999,系统Window的层级范围是2000~2999,这些层级属性范围对应着WindowManager.LayoutParamstype参数。

如果采用TYPE_SYSTEM_ERROR,只需要为type参数指定这个层级即可:

mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR

同时声明权限:<uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW" />

WindowManager所提供的功能很简单,常用的只有三个方法,即添加View更新View删除View,这三个方法定义在ViewManager中,而WindowManager继承了ViewManager。

WindowManager操作Window的过程更像是在操作Window中的View

Window的内部机制

Window是一个抽象的概念,并不是实际存在的,它是以View的形式存在,每一个Window都对应着一个View和一个ViewRootImpl,Window和View通过ViewRootImpl来建立联系。在实际使用中无法直接访问Window,对Window的访问必须通过WindowManager。

Window的添加过程

Window的添加过程需要通过WindowManageraddView()来实现,WindowManager是一个接口,它的真正实现是WindowManagerImpl类。WindowManager的实现类对于addView()updateView()removeView()方法都是委托给WindowManagerGlobal类。

WindowManagerGlobal的addView()方法分为如下几步:

  1. 检查参数是否合法,如果是子Window那么还需要调整一些布局参数
  2. 创建ViewRootImpl并将View添加到列表中。Window对应的View, ViewRootImpl和待删除的View对象都有对应的列表。
  3. 通过ViewRootImplsetView()来更新界面(View的绘制由ViewRootImpl完成),setView()中通过requestLayout()完成异步刷新请求
  4. 通过WindowSession来添加Window,添加过程的本质是一个IPC过程,其中用到了Binder对象IWindowSession(实现类Session),实际添加是交给WindowManagerService去处理
Window的删除过程

和添加过程一样,都是先通过WindowManagerImpl后,再进一步通过WindowManagerGlobal来实现的↓

调用removeView(),其中先找到待删除的View索引,然后调用removeViewLocked()->ViewRootImpl,有同步删除和异步删除,在异步删除中,就会发送一个信息,放进刚刚ViewRootImpl中的待删除View的列表。

真正删除View的逻辑在dispatchDetachedFromWindow()方法的内部实现。主要做四件事:

  1. 垃圾回收的工作,比如清除数据和消息,移除回调。
  2. 通过Session的remove方法删除Window,mWindowSession.remove(mWindow),这同样是一个IP C过程,最终会调用WindowManagerService的removeWindow方法
  3. 调用View的dispatchDetachedFromWindow方法,在内部调用View的onDetachedFromWindow()以及onDetachedFromWindowInternal()。
  4. 调用WindowManagerGlobal的doRemoveView方法刷新数据,包括mRoots、mParams以及mDyingViews,需要将当前Window所关联的这三类对象从列表中删除。
Window的更新过程

调用WindowManagerGlobal 的updateViewLayout():

首先需要更新View的LayoutParams并替换掉老的LayoutParams,接着再更新ViewRootImpl中的LayoutParams,这一步是通过ViewRootImpl的setLayoutParams()方法来实现的。在ViewRootImpl中会通过scheduleTrversals方法来对View重新布局,包括测量、布局、重绘三个过程。除了View本身的重绘以外,ViewRootImpl还会通过WindowSession来更新Window的视图,这个过程最终是由WindowManagerService的relayoutWindow()来具体实现的,同样是一个IPC过程。

Window的创建过程

Activity的Window创建过程

1、Activity的启动过程很复杂,最终会由ActivityThread中的performLaunchActivity()来完成整个启动过程,在这个方法内部会通过类加载器创建Activity的实例对象,并调用其attach()方法为其关联运行过程中所依赖的一系列上下文环境变量。

在attach()中,系统会创建所属的Window对象并设置回调接口。

Window对象的创建是通过PolicyManagermakeNewWindow() 实现

2、Activity实现了Window的Callback接口,当Window接收到外界的状态变化时就会调用Activity的方法,例如onAttachedToWindow()onDetachedFromWindow()dispatchTouchEvent()等。

3、Activity的Window是由PolicyManager来创建的 - > 真正实现是Policy类,它会新建一个PhoneWindow对象,Activity的setContentView()的实现是由PhoneWindow来实现的/

PhoneWindowsetContentView()方法大致遵循如下几个步骤:

  1. 如果没有DecorView(FrameLayout,顶级View,包含内容和标题栏),那么就创建它,通过gernerateLayout()加载具体的布局文件。
  2. 将View添加到DecorView的mContentParent中,
  3. 回调Activity的onCreateChanged()方法通知Activity视图已经发生改变

Window更多表示的是一种抽象的功能集合…

Dialog的Window创建过程

Dialog的Window的创建过程和Activity类似,有如下步骤:

  1. 创建Window:Diolog中Window的创建同样是通过PolicyManager的makeNewWindow()方法来完成的,创建后的对象实际上就是PhoneWindow。
  2. 初始化DecorView并将Dialog的视图添加到DecorView中,与Activity类似。
  3. 调用Dialog的show(),将DecorView添加到Window中并显示, 也与Activity类似。
  4. 普通的Dialog有一个特殊之处,就是必须采用Activity的Context,如果采用Application的Context,那么就会报错 -> 应用token只有Activity拥有,所以这里只需要Activity作为Context来显示对话框即可。

系统Window比较特殊,不需要token,系统Window的层级范围type: 2000~2999,可以指定Dialog的Window类型为系统Window。

dialog.getWindow().setType(LayoutParams.TYPE_SYSTEM_ERROR);
//要声明权限

Toast的Window创建过程

  • 在Toast的内部有两类IPC过程,第一类是Toast访问NotificationManagerService,第二类是NotificationManagerService回调Toast里的TN接口。
  • Toast属于系统Window,它内部的视图由两种方式指定:一种是系统默认的演示,另一种是通过setView方法来指定一个自定义的View
  • Toast具有定时取消功能,所以系统采用了Handler。
  • Toast的显示show()和隐藏cancel()是IPC过程,都需要NotificationManagerService(NMS)来实现,在Toast和NMS进行IPC过程时,NMS会跨进程回调Toast中的TN类中的方法,TN类是一个Binder类,运行在Binder线程池中,所以需要通过Handler将其切换到当前发送Toast请求所在的线程,因为使用了Handler,所以Toast无法在没有Looper的线程中弹出。

对于非系统应用来说,mToastQueue最多能同时存在50个ToastRecord(应用的mToastQueue队列最多只能存在50个),这样做是为了防止DOS(Denial of Service,拒绝服务)。因为如果某个应用弹出太多的Toast会导致其他应用没有机会弹出Toast。

  • Toast的显示是通过ToastRecord的callback来完成,callback -> Tn对象的远程Binder,需要跨进程,会运行在Toast的应用的Binder线程池中。

  • 并且会发送一个延时消息,时长取决于Toast的持续时长,用来调用cancelToastLocked来隐藏Toast,并且从队列中移除,然后继续显示队列中的Toast

Toast的显示和隐藏实际上通过Toast的TN类中的两个Runnable --> handleShow()handleHide() 方法,用于将Toast的视图从Window添加或者移除。

相关文章:

【Android】Window和WindowManager

文章目录 理解Window和WindowManagerWindow和WindowManagerWindow的内部机制Window的添加过程Window的删除过程Window的更新过程 Window的创建过程Activity的Window创建过程Dialog的Window创建过程Toast的Window创建过程 理解Window和WindowManager Window是一个抽象类&#xf…...

如何解决 Python ModuleNotFoundError 错误

模块对于开发 Python 程序很重要。 使用模块&#xff0c;我们可以分离代码库的不同部分以便于管理。 使用模块时&#xff0c;了解它们的工作方式以及如何将它们导入我们的代码非常重要。 如果没有这种理解或错误&#xff0c;我们可能会遇到不同的错误。 此类错误的一个示例是…...

Day62.算法训练

718. 最长重复子数组 class Solution {public int findLength(int[] nums1, int[] nums2) {int max 0;int[][] dp new int[nums1.length][nums2.length];for (int i 0; i < nums1.length; i) {for (int j 0; j < nums2.length; j) {if (nums1[i] nums2[j]) {if (i …...

Linux smbd命令教程:如何配置和管理Samba服务器(附案例详解和注意事项)

Linux smbd命令介绍 smbd是Samba套件的一部分。smbd是一个服务器守护进程&#xff0c;为Windows客户端提供文件共享和打印服务。服务器使用SMB&#xff08;或CIFS&#xff09;协议为客户端提供文件空间和打印服务。这与LanManager协议兼容&#xff0c;可以为LanManager客户端提…...

音视频学习(十九)——rtsp收流(tcp方式)

前言 本文主要介绍以tcp方式实现rtsp拉流。 流程图 流程说明: 客户端发起tcp请求&#xff0c;如向真实相机设备请求&#xff0c;端口一般默认554&#xff1b;tcp连接成功&#xff0c;客户端与服务端开始rtsp信令交互&#xff1b;客户端收到play命令响应后&#xff0c;开启线…...

LangChain(0.0.340)官方文档三:Prompts上——自定义提示模板、使用实时特征或少量示例创建提示模板

文章目录 一、 Prompt templates1.1 langchain_core.prompts1.2 PromptTemplate1.2.1 简介1.2.2 ICEL1.2.3 Validate template 1.3 ChatPromptTemplate1.3.1 使用role创建1.3.2 使用MessagePromptTemplate创建1.3.3 自定义MessagePromptTemplate1.3.3.1 自定义消息角色名1.3.3.…...

【算法】合并K个升序链表

这道题主要考察的是归并排序&#xff0c;因为已经升序过了&#xff0c;更好理解了。 当然也可以采用分治的思路&#xff1b;或采用最小堆的思路&#xff1b;面试中校招同学写出一种即可&#xff0c;如果能全概览讲一下&#xff0c;就更加分了。 #############################…...

持续集成交付CICD:GitLab Webhook触发Jenkins流水线

目录 一、实验 1.Jenkins远程下载GiaLab仓库代码 2.curl远程触发Jenkins流水线 3.GitLab Webhook触发Jenkins流水线 二、问题 1.GitLab配置Webhook时报错 一、实验 1.Jenkins远程下载GiaLab仓库代码 (1) Jenkins添加选项参数 (2)添加字符参数 (3)查看构建参数情况 (4)添…...

计算机网络测试题

一 单项选择题(5分) 1、假设要发送的数据为101110&#xff0c;采用CRC的生成多项式是X31&#xff0c;试求应添加在数据后面的余数。&#xff08;5分&#xff09; 110 011&#xff08;答案&#xff09; 101 001 实际得分&#xff1a;5分 二 填空题(95分) 1、以下3个子地址块…...

vscode如何在没有网络的情况下安装插件

vscode如何在没有网络的情况下安装插件 start 遇到没有网络的电脑&#xff0c;无法直接从插件市场安装vscode的插件。写一下 vscode 插件离线安装的方法. 解决方案 目标电脑没有可以安装插件的网络&#xff0c;那我们只能在有网络的环境下载好我们的插件。然后拷贝软件到无…...

自定义类型:结构体、联合、枚举

目录 一、⾃定义类型&#xff1a;结构体 1.结构体类型 1. 1结构体类型的声明 结构体变量的创建和初始化 1.2 结构的特殊声明 1.3 结构的自引用 2. 结构体内存对齐 ①&#xff1a;对齐规则 ②&#xff1a;offsetof函数 ③&#xff1a;为什么存在内存对⻬? ④ 修改默认对⻬…...

HelpLook可以作为wordpress的替代品,帮助企业快速搭建博客

博客作为一个非常有价值的平台&#xff0c;在当今的数字时代具有重要的意义。对于个人和企业来说&#xff0c;选择一款适合自己需求的专业博客搭建软件至关重要。本篇文章将会通过对比两个专业的博客搭建软件——HelpLook和WordPress&#xff0c;看看为什么我说HelpLook可以作为…...

单片机实现数码管动态显示

动态显示的特点是将所有位数码管的段选线并联在一起&#xff0c;由位选线控制是哪一位数码管有效。这样一来&#xff0c;就没有必要每一位数码管配一个锁存器&#xff0c;从而大大地简化了硬件电路。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码…...

jbrowse基因组浏览器部署

一、jbrowse部署 1.1 jbrowse部署 sudo mkdir /var/www/jbrowse; sudo chown whoami /var/www/jbrowse; # cd into it cd /var/www/jbrowse;1.2 nginx配置 server {listen 80 default_server;listen [::]:80 default_server;server_name _;#root /var/w…...

神经网络 模型表示(一)

神经网络 模型表示 模型表示一 为了构建神经网络模型&#xff0c;我们需要首先思考大脑中的神经网络是怎样的&#xff1f;每一个神经元都可以被认为是一个处理单元/神经核&#xff08;processing unit/Nucleus&#xff09;&#xff0c;它含有许多输入/树突&#xff08;input/…...

【漏洞复现】智跃人力资源管理系统GenerateEntityFromTable.aspx接口存在SQL注入漏洞 附POC

漏洞描述 智跃人力资源管理系统是基于B/S网页端广域网平台,一套考勤系统即可对全国各地多个分公司进行统一管控,成本更低。信息共享更快。跨平台,跨电子设备。智跃人力资源管理系统GenerateEntityFromTable.aspx接口处存在SQL注入漏洞,攻击者可通过该漏洞获取数据库中的信…...

【matlab程序】画海洋流场

【matlab程序】画海洋流场 clear;clc; file ( ‘0227.nc’); latncread(file,‘latitude’); lonncread(file,‘longitude’); uncread(file,‘water_u’); vncread(file,‘water_v’); [x,y]meshgrid(lon,lat); xx’; yy’; interval4; figure (1) set(gcf,‘color’,[1 1 1…...

线性表 力扣67. 二进制求和

题目 67. 二进制求和 翻译 主要思路 核心思路是像竖式计算一样&#xff0c;不过需要将字符串a和b反转后逐位进行二进制计算得到字符串c&#xff0c;最后再将c反转就是答案 逐位计算的时候利用count&#xff0c;在将a和b当前位置数字相加后通过模2来决定字符串c对应位置的数…...

2312skia,13画布包入门

画矶包快速入门 CanvasKit是用比canvasAPI更高级功能集的Skia来绘画元素到canvas中的wasm模块. 最小应用 此例是个最小Canvaskit应用,它为一帧绘画一个圆角矩形.从unpkg.com中提取wasm二进制文件,但你也可自己构建和管理它. <canvas idfoo width300 height300></c…...

【网络安全技术】消息认证技术

一、哈希函数 1.安全性质 1&#xff09;抗第一原像攻击&#xff08;Preimage Resistance&#xff09; 给定哈希后的值&#xff0c;很难找到哈希前的原消息。这很好理解&#xff0c;需要哈希函数具有单向性。 一个简单的例子就是密码存储系统&#xff0c;用户登录服务器需要…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…...