WindowManager
Android 大部分的系统Services 都运行在 System Server 这个进程里,用一个简单的方法来看看都有哪些重要的Service, “ps -t | grep <system_server pid>"
看看,System_Server进程有多繁重,里面有这么多的线程,图中黄色高亮的是各个service的主服务线程,每个service都会有一个服务主线程和若干个后台线程,实际运行中数量会动态增长,因为应用程序对Service 接口的远程调用会运行在专门的Binder线程
因此一般情况下,我们可以说,一个应用可以有多个Activity,每个 Activity 一个Window(PhoneWindow), 每个Window 有一个DecorView, 一个ViewRootImpl, 对应在WindowManagerService 里有一个Window(WindowState).
( ViewRootImpl, WindowManagerImpl, WindowManagerGlobal) 都存在于应用(有Activity)的进程空间里,一个Activity对应一个WindowManagerImpl, 一个DecorView(ViewRoot),以及一个ViewRootImpl (上面说过,实际一个Activity只有一个DecorView),而WindowManagerGlobals是一个全局对象,一个应用永远只有一 个。注意的是,在某些情况下,一个应用可能会有几个ViewRootImpl对象,比如说ANR是弹出的对话框,或是网页里面一个视频窗口 (SurfaceView), 在WindowManagerService看来,它们也是一个窗口。同时,SystemServer的进程空间也有自己的 WindowManagerGlobals 和若干个ViewRoot, 因为WindowManagerService 内部也会管理某些系统窗口,如手机顶部的StatusBar, 手机底部的NavigationBar, 以及 锁屏(KeyGuard)窗口,这些窗口不属于某个特定的Activity。
WindowManager: 是一个接口类,定义了一些接口来管理Acitivity里的窗口。WindowManager 是Android应用进程空间里的一个对象,不提供IPC服务。
WindowManagerService: 是SystemServer进程里的一个Service,它的主要功能有
窗 口的显示刷新。这里的’Window’ 其实是ViewRoot, 和上面WindowManager管理的’Window’ 是不一样的,前者是实实在在要进行显示的‘窗口’, 而后者只是一个View的容器,并不会显示出来。大部分情况下,Android同时只有一个Activity工作,但这并不意思着只有一个Window被 显示,Android可能会同时显示来自相同或不同应用的多个Window,比如说,屏幕的上方有一个状态栏,最下方有一个导航栏,有时会弹出一些对话 框,背景可能会显示墙纸,在应用启动过程中,会有动画效果,这个时候两个Activity的窗口会有所变形且同时显示出来,这一切都需要 WindowManager来控制何时,何地,以何种方式将所有的窗口整合在一起显示。
预处理用户输入时间(GlobalKey? SystemKey), 并分发给合适的窗口进行处理。
输出显示(Display)管理。包括WifiDisplay.
1、View和ViewRoot
ViewRoot从名称上来理解似乎是“View树的根”,这很容易让人产生误解。因为ViewRoot并不属于View树的一份子。从源码实现上来看,ViewRoot和View对象并没有任何“血缘”关系,它既非View的子类,也非View的父类。ViewRoot可以被理解为“View树的管理者”——它有一个mView成员变量,指向的是它所管理的View树的根。
在上图布局中,ViewRoot中的mView成员变量指向的就是它所管理的View树的根,即上图中的LinearLayout:test元素。ViewRoot的核心任务就是与WindowManagerService进行通信。 2、Activity和Window的关系 我们知道Activity是支持显示UI的,那么它是否直接管理view树或者ViewRoot呢?答案时否定的,Activity并没有与这两者产生直接的联系,因为这中间还有一个被称为“Window”的对象。大家可以在Activity的源码中找到如下代码:private Window mWindow; Window的字面意思是窗口,这很好地解释了它存在的意义。Window是基类,根据不同的产品可以衍生出不同的子类——具体则是由系统在Activity.attach中调用PolicyManager.makeNewWindow决定的,目前版本的Android系统默认生成的都是PhoneWindo。 3、Window和WindowManagerImpl的关系 在Android源码中以“Window”开头的类有不少,如Window,WindowManager,WindowManagerImpl等,为什么需要这么多相似的类呢? 先来看Window,它是面向Activity的,表示UI界面的外框;而“框里面”具体的东西包括布局和内容等,是由具体的Window子类,如PhoneWindow来规划的。 Window的另一层含义是要与WindowManagerService进行通信,但它并没有直接在自身实现这一功能。原因是:一个应用程序中很可能存在多个Window。如果它们都单独与WMS通信,那么既浪费资源,又会造成管理的混乱。换句话说,它们需要统一的管理。于是就有了WindowManager,它作为Window的成员变量mWindowManager存在。这个WindowManager是一个接口类,其真正的实现是WindowManagerImpl,后者同时也是整个应用程序中所有Window的管理者。因而WindowManager与WindowManagerImpl的关系有点类似于“地方与中央”:地方为实施中央的“政策”提供了一个接口,然后汇总到中央进行管理。 在Window的源码中与mWindowMager有关的代码有如下几句:
private WindowManager mWindowManager;
public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) {mAppToken = appToken;mAppName = appName;mHardwareAccelerated = hardwareAccelerated|| SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);if (wm == null) {wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);}**mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);**}public WindowManager getWindowManager() {return mWindowManager;}
然后我们去WindowManagerImpl的代码中去查看createLocalWindowManager方法的代码,代码如下:
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {return new WindowManagerImpl(mDisplay, parentWindow);}
从这几处代码,大家可以看到Window类中的mWindowManger引用的其实是WindowManagerImpl的实例。
4、ViewRoot和WindowManagerImpl的关系:
在早期的系统版本中,WindowManagerImpl在每个进程中只有一个实例。调用它必须使用如下语句:
WindowManagerImpl.getDefault();
在WindowMangerImpl内部,存在3个全局变量:(下图中的源码是2.3.5中的)
它们分别用于表示View树的根节点、ViewRoot以及Window的属性。由此也可以看出,一个进程中不仅有一个ViewRoot;而Activity与ViewRoot则是一对一的关系。自Android4.3开始对此做了修改,WindowManagerImpl不再直接存储上述三个数组变量,而是由一个称为“WindowMangerGlobal”的类统一管理。 5、ViewRoot和WindowManagerService的关系 每一个ViewRootImpl内部,都有一个全局变量 static IWindowSession sWindowSession; 这个变量用于ViewRoot到WMS的连接,它是ViewRoot利用WMS的openSession()接口来创建得到的。在此基础上,ViewRoot也会通过IWindowSession.add()方法提供一个IWindow对象——从而让WMS也可以通过这个IBinder对象来与ViewRoot进行双向通信。 这里突然间冒出一个ViewRootImpl类,其实ViewRoot与ViewRootImpl的功能是一样的,只不过是Android不同版本的不同称呼。不信看下图:
其实每个Application都有一个ActivityThread主线程以及mActivities全局变量,后者记录了运行在应用程序中的所有Activity对象。一个Activity对应唯一的WindowManager以及ViewRootImpl。WindowManagerGlobal作为全局管理者,其内部的mRoots和mViews记录了Activity的ViewRootImpl和View树的顶层元素。ViewRootImpl的另一个重要角色就是负责与WMS通信。从ViewRootImpl到WMS间的通信利用的是IWindowSession,而反方向则是由IWindow来完成的。 最后补充说明一点:Activity中有一个成员变量mWindow,mWindow里面有一个成员变量mWindowManager,而mWindowManager是WindowMangerImpl类实例的引用,另外WindowMangerImpl里面包含ViewRoot(不管老版本中直接包含,还是新版本中间接包含)。 本篇博文只是为了记录我对于ViewRoot以及与ViewRoot相关的一些概念的了解。
在WindowManager中,addView方法表示的是将主窗口中的顶级view(也就是DecorView)添加到WindowManager中,并建立会话。
ActivityThead中的两个重要的方法(至于ActivityThead将在一篇中详细介绍):
performLaunchActivity( );
handleResumeActivity( );
在performLaunchActivity中,会调用activity.attach方法建立一个window, 在handleResumeActivity方法中启动activity的时候,会将主窗口加入到WindowManager中
View decor =r.window.getDecorView(); //获得窗口的顶级Viewdecor.setVisibility(View.INVISIBLE);ViewManager wm= a.getWindowManager(); //WindowManager继承自ViewManagerWindowManager.LayoutParams l =r.window.getAttributes();a.mDecor = decor;l.type =WindowManager.LayoutParams.TYPE_BASE_APPLICATION;l.softInputMode |= forwardBit;if (a.mVisibleFromClient) {a.mWindowAdded = true;wm.addView(decor, l); //实际上是把主窗口的顶级view加入到WindowMangaer}
public ViewRootImpl(Context context, Display display) {//在WMS服务中创建Session Binder对象,同时返回Binder代理对象给当前应用程序进程,并保存在ViewRootImpl的成员变量mWindowSession中mWindowSession = WindowManagerGlobal.getWindowSession();...//为每一个ViewRootImpl对象创建W Binder对象,用于WMS服务访问对应的ActivitymWindow = new W(this);...mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);...mChoreographer = Choreographer.getInstance();...loadSystemProperties();
}
在应用程序进程中启动的每一个Activity都拥有一个ViewRootImpl对象:
三 者( ViewRootImpl, WindowManagerImpl, WindowManagerGlobal) 都存在于应用的进程空间里,WindowManagerService存在与SystemService进程中,一个Activity对应一个WindowManagerImpl, 一个DecorView(ViewRoot),以及一个ViewRootImpl (上面说过,实际一个Activity只有一个DecorView),而WindowManagerGlobals是一个全局对象,一个应用永远只有一 个。
注意的是,在某些情况下,一个应用可能会有几个ViewRootImpl对象,比如说ANR是弹出的对话框,或是网页里面一个视频窗口 (SurfaceView), 在WindowManagerService看来,它们也是一个窗口。同时,SystemServer的进程空间也有自己的 WindowManagerGlobals 和若干个ViewRoot, 因为WindowManagerService 内部也会管理某些系统窗口,如手机顶部的StatusBar, 手机底部的NavigationBar, 以及 锁屏(KeyGuard)窗口,这些窗口不属于某个特定的Activity。
WindowManager相关推荐
- Android 中文 API (90) —— WindowManager
一.结构 public interface WindowManager extends android.view.ViewManager android.view.WindowManager 二.概述 ...
- Android WindowManager 解析与骗取 QQ 密码案例分析
最近在网上看见一个人在乌云上提了一个漏洞,应用可以开启一个后台 Service,检测当前顶部应用,如果为 QQ 或相关应用,就弹出一个自定义 window 用来诱骗用户输入账号密码,挺感兴趣的,总结相 ...
- android的WindowManager.addView弹窗添加
2019独角兽企业重金招聘Python工程师标准>>> touch here android在WindowManager添加View 作者:feiyangxiaomi [TOC] # ...
- WindowManager如何被Android深度解析(3)
前言 在此前的系列文章中我们学习了WindowManager体系和Window的属性,这一篇我们接着来讲Window的添加过程.建议阅读此篇文章前先阅读本系列的前两篇文章. 1.概述 WindowMa ...
- WindowManager如何被Android深度解析(1)
前言 WindowManagerService(WMS)和AMS一样,都是Android开发需要掌握的知识点,同样的,WMS也很复杂,需要多篇文章来进行讲解,为何更好的理解WMS,首先要了解Windo ...
- WindowManager如何被Android深度解析(2)
1.概述 上一篇文章中我们讲过了Window.WindowManager和WMS之间的关系,WMS是Window的最终管理者,Window好比是员工,WMS是老板,为了方便老板管理员工则需要定义一些& ...
- Android基础建设之Activity,ViewRoot,WindowManager,Window,View
一个Activity 对应一个WindowManager 对应一个Window 对应一个DecorView 对应一个Feature确定的Layout 但是对应多个ViewRoot. 对应多个Dialo ...
- WindowManager.LayoutParams各种flag含义
本文实际上就是翻译了官方文档的flag部分,以便使用的时候对照. flags变量设置的值的各种意义//---------------1--------------------------------- ...
- WindowManager.LayoutParams类22
引用:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=84893 WindowManager.LayoutParams 是 Win ...
- Android开发艺术探索》读书笔记 (8) 第8章 理解Window和WindowManager
第8章 理解Window和WindowManager 8.1 Window和WindowManager (1)Window是抽象类,具体实现是PhoneWindow,通过WindowManager就可 ...
最新文章
- Nginx(二) 配置与调试
- SMTP 通过 ssh 通道发送垃圾邮件
- 产品如何解决「发型师」与「消费者」的认知偏差?
- Recurrent Neural Networks Tutorial, Part 1 – Introduction to RNNs
- 实战|对某棋牌站的一次getshell
- SQL优化技巧--远程连接对象引起的CTE性能问题
- 功能测试常用6种方法_16种常用的数据分析方法聚类分析
- Java中number数字类型的转换_Java下数字类型的转换 (转)
- 【Poj1017】Packets
- linux 安腾,时代谢幕:英特尔安腾IA-64的Linux内核支持已成孤儿
- 喜马拉雅音频批量下载
- MapServer+OpenLayers5+Vue实现栅格图层数据查询
- Day 2: 数据类型的使用,字符编码
- 化繁为简,弱监督目标定位领域的新SOTA - 伪监督目标定位方法(PSOL) | CVPR 2020
- 解读《大话西游之大圣娶亲》
- SOME/IP与DDS对比及DDS测试策略和方案探讨
- 商汤科技面试——AI算法岗
- 验证sqlserver 2000 sp4补丁是否安装成功(安装补丁后可以远程访问)
- java使用itextpdf生成PDF批量打印荣誉证书(指定位置输出文字)
- 重定向--Linux bash
热门文章
- 谷歌5.5亿美元投资京东:乍看很壮观,细思然并卵
- 有道云笔记Markdown如何停止/结束一段引用
- 中国重大计算机病毒事件,新型电脑病毒INCASEFORMAT在国内大面积爆发,重要通知,重要事情说三遍,备份、备份、备份!...
- Android仿QQ圆形头像
- linux记录端口访问日志,Linux日志管理
- tomcat注册windows服务-歪解
- 针对苹果最新审核要求为应用兼容IPv6
- java随机生成姓名、电话、邮箱、时间
- 找出两个List集合重复的元素
- ASP.NET Core源码学习(一)Hosting