Copyright:http://blog.csdn.net/myzhzygh/article/details/8470469

1.Introduce

本文档的主要目的是记录Android 窗口子系统的研究成果,同时帮助读者理解Android窗口管理的基本概念和窗口管理的基本框架。文章后续段落内容安排如下:

首先,我们从应用程序的角度出发,对参与窗口管理的各个Module,通过图示的方式向读者展示它们之间的关系,帮助读者从宏观上建立窗口管理的概念。其次,我们会从窗口管理的整体结构出发,讲述窗口管理的Client和Server空间构成以及他们之间的结构关系。最后,我们会列出窗口管理涉及到的关键数据结构,针对这些数据结构的深入理解需要读者结合Android Source Code进行学习。

2.The Relationship between Application and WMS

参与窗口管理的Module,从源码角度来说是特别多,但由于Android窗口管理采用了C/S结构,所以从整体结构划分,对于一个确定的Module要么属于Client端,要么属于Service端。从这个角度出发我们就很容易理解窗口管理各个Module的生命周期和具体功能。所以在理解的时候,我们更多的应该以接口的概念去理解他们之间的关系,同时在理解的过程中要有进程空间的概念。为了文档书写方便,文档后续出现的缩写WMS代表WindowManagerService;AMS代表ActivityManagerService。

Application,Session与WMS之间的关系图,从应用程序的角度展现了Android系统窗口管理的宏观结构。从图中我们可以看到每一个Application与WMS交互的过程中,它们各自处于自己的Session之中。所以说系统中启动了多少个对View有需求的Application,系统中就会有多少个Session存在。而这些Session实例都由WMS统一维护和管理。

2.2 Application,ViewManager和Session之间的关系:

每个Application实例对应一个ViewManager实例, ViewManager负责管理Application内部所有的View,从图中我们可以看到,这里的ViewManager并不是一个独立的Service,它是Application的一个组成部分,换句话说就是应用程序中的一个数据结构,但这个结构的实例对于应用程序是一个单例模式。我们之前讲到一个Application对应一个Session,同样也是因为对于一个确定的Application,其内部维护的由WMS分配的Session实例也是一个单例模式。

2.3 Application,View,ViewGroup和ViewManager之间的关系:

每个Application可以有多个View存在,这些View都属于这个Application,它们都由Application内部的ViewManager统一管理和维护,针对这些View的管理主要包括View的添加,删除和更新操作。而多个View又可以组成一个或多个ViewGroup。ViewGroup本身可以认为就是一个逻辑单元,它也是一个View。只是它可以包含其它的View或ViewGroup。图中的View,ViewManager都属于各自Application进程空间。

从之前的分析我们知道,在Android系统中,Application与WMS之间的交互处于各自的Session之中,每个Application通过ViewManager对其内部的所有View进行管理;Application内部的View可以以单个View或ViewGroup的形式存在。

2.4 Application,Activity,Session,WindowState和WMS之间的关系:

在此之前我们都是从Application的角度出发,去观察和分析与窗口管理有关的各个Component之间的关系。我们知道与View打交道的模块,肯定是有显示需求的模块,至少是属于展现层的模块。在Android中,Application只是一个宏观结构,包含多个Components, 更多的是充当一个资源容器的概念,但并不是所有的Components都有View需求。Application的所有Components中,只有Activity Component是直接与View进行交互的。所以接下来,我们对Application与窗口管理之间关系的研究将落实到Activity与窗口管理之间的关系研究上。

一个Application可以包含多个Activity,而一个Activity又可以包含嵌套其它的Activity和View。所以从功能上说Activity就应该至少包含一个View或ViewGroup。在实际窗口管理中,Application的概念会被淡化,只是作为Activity及应用程序其它资源的容器。而参与窗口管理更多的是Activity,或者说是Activity的View。

我们知道一个Application对应一个Session, 那么属于一个Application的所有Activity都工作在同一个Session中,如图4所示。

图5向我们展示了Application,Activity,Window,Session和WMS之间的关系,一般情况下,一个Activity会创建一个Window,而一个Window在WMS内部对应一个WindowState。

当然,如果一个Activity内部包含了特殊的View,或者在创建过程中创建了对话框类型,Popup类型的其它组件,或者通过ViewManager将View直接加入WMS,在这些情况下,那么一个Activity就会创建多个Window,相应的WMS中也会对应多个WindowState,如图6所示:

接下来我们会看到在单独的一个Session空间内,一个普通的Activity(不包含特殊View和其它类型Window)内部View构成,以及它与WMS之间的关系。

首先我们看到在Activity空间内,有DecorView, View,ViewGroup。其中DecorView是一个相对比较抽象的概念,我们可以把它理解为窗口的根View,或者说它与窗口直接关联;他们共同构成了Activity的View系统,当然他们之间的界限并不是特别明确,并不是每一个Activity必须完全包含这三个View组件,可能把View和Window联系起来更容易理解,而不是把View和Activity联系起来。对应的在WMS空间内与这个Activity对应的两个重要结构分别是AppWindowToken和WindowState。AppWindowToken是Activity在WMS空间内的表示,或者映射元素;WindowState是Window,或者说是Window对应的根View(DecorView)在WMS空间内的表示。

当一个Activity启动之后,首先它会向WMS中添加相应的AppWindowToken,当然添加AppWindowToken的动作并不是由Activity直接发出的,而是由AMS向WMS发起的。随后在向WMS内添加Window根View(DecorView)的时候创建对应的WindowState。添加Window的过程如下图所示:

Activity首先要附着在一个主窗口之上。Android中的Window表示Top-Level顶级窗口的概念。DecorView是Window的Top-Level View,是Window的根View,之前说过,Activity会附着在主窗口上,更准确的应该说是DecorView需要附着在主窗口上。主View在底层对应ViewRoot对象,然后通过ViewRoot将构造一个IWindow对象,然后通过这个IWindow对象将该View加入到WMS中,WMS使用WindowState与这个View对应,WindowState中引用该View对应的IWindow对象,通过该对象WindowState可以回调客户端的方法,与客户端进行通信。

ViewRoot实际是一个Handle,ViewRoot建立主View与WMS通讯的桥梁。ViewRoot在本质上是一个Handle,那么它的主要责任就是负责处理回调和发送消息。具体负责将Client端的请求发送给Server端的WMS,同时它接收WMS端的消息,把它分发给Client端的View。

一个完整的窗口概念横跨了View, ViewRoot, WMS。对于Android窗口管理的C/S结构,作为Client端的Activity通过Session会话与WindowManagerService建立对话,而作为Server端的WMS则通过IWindow接口访问Client,将消息传递到Client端,再通过Client端的消息分发渠道,将消息发送到具体的View上。

3.Window Manager Architecture

窗口管理主要涉及两大部分,View显示和事件处理。和结合文档前一章节的的图示,我们就以Activity作为我们狭义上窗口管理的Client端。从最初对窗口管理的认识出发,那么Client端最重要的数据结构应该是Window。实际上,我们通过前面的分析,Client端最重要的结构应该是Window的根View,即DecorView。Android系统中Window作为对窗口的抽象类,它描述了一个窗口所具有的特征。而通过为Window添加根View,才真正的与WMS之间建立起窗口管理的通道。Client端的空间如下图所示:

在Activity在performLaunchActivity()时,会使用Activity.attach()建立PhoneWindow主窗口。DecorView实际上是一个ViewGroup,从View之间的层次关系上来讲,对主窗口来说DecorView是Top-Level View。handleResumeActivity真正要启动一个Activity时,会将主窗口的DecorView通过ViewManager最终加入到WMS中。

Window在Client端不同阶段的抽象描述我们可以认为分别是DecorView,ViewRoot。那么Window在和Server端的核心抽象描述为WindowState。WMS作为Android窗口管理的核心,包含了窗口管理的两大核心系统:显示系统和输入系统。随着Android系统的不断发展,Android窗口管理系统也发生了很多变化,尤其是在输入事件处理上有很大的改变。

图10展现了Android系统窗口管理的结构。图中描述了从Activity启动,添加View到它能接收并处理事件的一个过程:包括焦点切换流程和输入事件处理流程。

首先:我们从标示为Views的部分出发,这个区域可以对应所有的Activity空间,或者对应所有的ViewRoot。在这里我们以普通Activity为例,对于每一个Activity,我们要启动它,需要完成两件事:向AMS发送启动请求,要求启动该Activity,向WMS发送请求,添加该Activity附着窗口的DecorView。也就是图中V--àA和V--àW两条路径。这两个过程并不是单一并行的,应该说是相互伴随,首先在V--àA的过程中,AMS会将Activity对应的AppWindowToken添加到WMS中,这个过程可以用A--àW路径表示,要明确的是并不是A--àW路径只表示添加Activity 的Token。随后进入Activity向WMS请求添加Window根View的过程中,也就是V--àW表示的路径。首先获取该Activity对应的AppWindowToken, 然后以此来创建对应的WindowState。并在创建的过程中创建该WindowState的InputHandle实例,在底层完成创建之后将InputEvent Channel的client端返回给Activity,也就是ViewRoot。这个过程可以用图中W--àH和W---àA的过程。W--àH是通过InputManager创建接收输入事件的通道Channel,然后把这个Channel的一端通过W--àA返回给A端。这里利用了Linux命名管道技术,这样A端就可以利用返回的Channel描述符直接读取H端的KeyEvent和MotionEvent两种事件,事件传递的过程也就是H-àChannel,Channel-àA的过程。在Activity启动之后,由于Activity的启动,View的焦点随之发生了变化,AMS会向WMS发送消息,通知WMS当前Focus Activity是谁,也就是A-àW过程。WMS通过当前FocusActivity,通过查自己的Z-order数组,找出属于该FocusActivity的WindowState,那么找到的这个WindowState就是Focus Window,然后再通过IWindow回调,通知Client端。

WindowManagerService的主要功能可以总结如下:

(1)窗口的Z-ordered的维护,主要包括窗口栈的管理,栈序调整;

(2)窗口的添加,移除;

(3)窗口的Layout;

(4)Token管理,负责窗口与应用之间的对应;

(5)活动窗口管理,也就是Focus Window;

(6)创建窗口的Starting和Ending过渡动画;

(7)系统输入事件收集和分发;

(8)Client端通知和回调;

4.Focus Path

View的成员变量mParent用来管理View的上级关系,而ViewGroup作为一组View的管理者,ViewGroup中够早了焦点管理和子View节点数组,这样通过View的mParent和ViewGroup的mChildren能够构造Android中View的直接关系树。如图11所示:

所谓的Focus Path就是KeyEvent传递的路线。主View通过View的焦点记录关系传递到焦点View上。如图12,View22是焦点,我们从最顶层的View通过mFocus的关系链找到最后所形成的路径就是Focus Path,如图中红线标示的路径。

KeyEvent事件的分发也就是沿着Focus Path最终到达Focus View,最终被处理。

5.Key Data Structure

Window:

IWindow:

WindowManager:

WindowManager.LayoutParams:

View:

ViewGroup:

ViewRoot:

ActivityClientRecord:在performLaunchActivity(handleLaunchActivity,handleRelaunchActivity最终都会调用他)之前,都需要先构造一个ActivityClientRecord类的对象。这个对象包含了创建Application和Activity所有的信息,是启动应用程序必须的数据结构。

ActivityRecord:

AcvivityManagerService(AMS): 主要管理Activity, service的加载,卸载,应用的创建等,当在一个应用程序中调用StartActivity时,应用就通过IPC机制向System Service请求启动新的Activity,System Service首先会查找,这个Activity是否已经被创建,如果没有,查找这个Activity所在的应用程序是否已经起来,如果没有就先启动应用。然后向此应用发送launchActivity消息创建Activity。

WindowToken

AppWindowToken

WindowState

WindowManagerService(WMS):主要管理窗体的加载,事件的分发。启动每个Activity,系统都会创建一个ViewRoot用于保存所有的View,通过ViewRoot将窗体加载到 WindowManagerService并创建窗体的客户端,当服务程序接收到按键事件后,就会查找当前窗体是否是焦点控件,如果是的话就会将窗体事件通过客户端IPC传递到相应的应用程序,如果在焦点View中有注册接收KeyEvent的消息则事件就在该View中得到处理。

PhoneWindowManager

InputManager:

InputDispatch:

InputReader:

Android Window Manager Subsystem Research相关推荐

  1. android window manager

    一.概述 在Android系统中,从设计的角度来看,窗口管理系统是基于C/S模式的.整个窗口系统分为服务端和客户端两大部分,客户端负责请求创建窗口和使用窗口,服务端完成窗口的维护,窗口显示等. 在Cl ...

  2. 图解Android - Android GUI 系统 (2) - 窗口管理 (View, Canvas, Window Manager)

    Android 的窗口管理系统 (View, Canvas, WindowManager) 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道And ...

  3. java.lang.IllegalArgumentException: View=DecorView not attached to window manager(Android Dialog崩溃)

    监控报警,Dialog偶现Crash.日志如下: java.lang.IllegalArgumentException: View=DecorView@9d9a86 not attached to w ...

  4. Android—Window、WindowManage、屏幕绘制及刷新

    Activity窗口层级: 所以在onCreate方法体中setContentView方法都是设置DecorView的ContentView. Window.PhoneWindow.DecorView ...

  5. Android Window 9问9答

    1.简述一下window是什么?在android体系里 扮演什么角色? 答:window就是一个抽象类,他的实现类是phoneWindow.我们一般通过windowManager 来访问window. ...

  6. 【Android】Android Window

    1,Window和View的关系 View必须依托于Window这个抽象该类存在,通过Window实现View的变化, Activity的启动过程,View和Window的联系发生在ActivityT ...

  7. Android Window系列(一)- window与decorview

    概述 window是android中非常常见的一个概念.Activity.Dialog.Toast这些常用的知识点都是和window密不可分的. 因此,笔者整理了下window相关的知识,期望能对需要 ...

  8. android 东软pda扫描适配_【Android】如何在线更新Android SDK Manager里的各种工具

    遇到这种情况,说明你需要更新Android SDK Tools了,可是现在禁了goole,该如何更新呢?当然是走镜像地址了. Step1:选择 Window -> Android SDK Man ...

  9. (转)解决Android SDK Manager无法更新或下载太慢问题

    (转)解决Android SDK Manager无法更新或下载太慢问题 参考文章: (1)(转)解决Android SDK Manager无法更新或下载太慢问题 (2)https://www.cnbl ...

最新文章

  1. 《Git的奇技淫巧》.PDF
  2. 解决服务器上 w3wp.exe 和 sqlservr.exe 的内存占用率居高不下的方案
  3. [Linux] 编写Dockerfile文件自动构建镜像
  4. jmeter接口测试----9函数助手: random, counter, time
  5. Juventas, the Roman Goddess of Youth [ Juventas, 罗马青春女神]
  6. maven 引入war
  7. Java复习总结(二)Java SE 面试题
  8. python pytorch自定义_Pytorch 实现自定义参数层的例子
  9. 计算机相关专业的学生如何规划自己的职业?
  10. endnote初始化数据库支持_学术干货:Endnote免费网页版竟如此强大!
  11. web文件管理系统_实用开源项目,基于Web的文件管理系统——DocSys
  12. Android bluetooth介绍(三): 蓝牙扫描(scan)设备分析
  13. 幼儿体能五项技能测试软件,卓艺湖畔幼儿园教师五项体能培训--器械游戏分享...
  14. 随便输入两个单词,两个单词之间以空格隔开,输出时每个单词的首字母变为大写。如输入:“hello java”,输出为“Hello Java”
  15. HashMap底层详讲
  16. v-for与v-if为什么不能同时用?
  17. React Native Apps的最佳主题
  18. Python - 在for循环体内修改i值
  19. WWW网上下载管理器
  20. 普度网络营销策划_普度网络营销策划:中小企业线上营销沙龙成功举办

热门文章

  1. 每天一分钟玩转golang:基础类型之浮点型(二)
  2. Matlab中pause函数的使用
  3. outlook 2007 如何设置开机自动启动
  4. PS5 舞力全开2022终极版支持摄像头与PSMove
  5. C#开发winform小知识点
  6. FDDDDDFSDSDGSDG
  7. 中国现代书画家——王晓宇、郭英杰、付正福等
  8. Linux 命令(165)—— whoami 命令
  9. c#Post请求响应案例
  10. 巨杉数据库5.0携手南天信息布局云业务