在前一个系列文章中,咱们从个体的角度来分析了Android应用程序窗口的实现框架。事实上,若是咱们从总体的角度来看,Android应用程序窗口的实现要更复杂,由于它们的类型和做用不一样,且会相互影响。在Android系统中,对系统中的全部窗口进行管理是窗口管理服务WindowManagerService的职责。在本文中,咱们就将简要介绍WindowManagerService的职能以及制定学习计划。算法
咱们知道,在Android系统中,同一时刻,只有一个Activity窗口是激活的,可是,对于WindowManagerService服务来讲,这并不意味着它每次只须要管理一个Activity窗口,例如,在两个Activity窗口的切换过程当中,先后两个Activity窗口实际上都是可见的。即便在只有一个Activity窗口是可见的时候,WindowManagerService服务仍然须要同时管理着多个窗口,这是由于可见的Activity窗口可能还会被设置了壁纸窗口(Wallpaper Winodw)或者弹出了子窗口(Sub Window),以及可能会出现状态栏(Status Bar)以及输入法窗口(Input Method Window),如图1所示。架构
图1 Activity窗口及其子窗口、壁纸窗口、输入法窗口和状态栏的位置结构框架
所以,WindowManagerService服务是不能够假设同一时刻它只须要管理一个窗口的,它须要经过各个窗口在屏幕上的位置以及大小来决定哪些窗口须要显示的以及要显在哪里,这实际上就是要计算出各个窗口的可见区域。ide
从前面Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析一文能够知道,SurfaceFlinger服务在渲染整个屏幕的UI的时候,会对各个窗品的可见性进行计算,所以,WindowManagerService服务只要将它所管理的各个窗品的位置以及大小告诉SurfaceFlinger服务,后者能够帮帮它计算出各个窗口的可见区域了。注意,这里,这里所说的窗口位置包括窗口在X、Y和Z轴的位置。函数
WindowManagerService服务大体按照如下方式来控制哪些窗口须要显示的以及要显在哪里:学习
1. 每个Activity窗口的大小都等于屏幕的大小,所以,只要对每个Activity窗口设置一个不一样的Z轴位置,而后就可使得位于最上面的,即当前被激活的Activity窗口,才是可见的。动画
2. 每个子窗口的Z轴位置都比它的父窗口大,可是大小要比父窗口小,这时候Activity窗口及其所弹出的子窗口均可以同时显示出来。orm
3. 对于非全屏Activity窗口来讲,它会在屏幕的上方留出一块区域,用来显示状态栏。这块留出来的区域称对于屏幕来讲,称为装饰区(decoration),而对于Activity窗口来讲,称为内容边衬区(Content Inset)。blog
4. 输入法窗口只有在须要的时候才会出现,它一样是出如今屏幕的装饰区或者说Activity窗口的内容边衬区的。接口
5. 对于壁纸窗口,它出现须要壁纸的Activity窗口的下方,这时候要求Activity窗口是半透明的,这样就能够将它后面的壁纸窗口一同显示出来。
6. 两个Activity窗口在切换过程,实际上就是前一个窗口显示退出动画然后一个窗口显示开始动画的过程,而在动画的显示过程,窗口的大小会有一个变化的过程,这样就致使先后两个Activity窗口的大小再也不都等于屏幕的大小,于是它们就有可能同时都处于可见的状态。事实上,Activity窗口的切换过程是至关复杂的,由于即将要显示的Activity窗口可能还会被设置一个启动窗口(Starting Window)。一个被设置了启动窗口的Activity窗口要等到它的启动窗口显示了以后才能够显示出来。
从以上六点就能够看出,窗口在X、Y和Z轴的位置及其大小的计算很是重要,它们共同决定了一个窗口是不是总体可见的,仍是部分可见的,或者总体不可见的。在Android系统中,WindowManagerService服务是经过一个实现了WindowManagerPolicy接口的策略类来计算一个窗口的位置和大小的。例如,在Phone平台上,这个策略类就是PhoneWindowManager。这样作的好处就是对于不一样的平台实现不一样的策略类来达到不一样的窗口控制模式。
从上面的描述就能够看出,WindowManagerService服务除了要与Activity窗口所运行在的应用程序进程打交道以外,还须要与SurfaceFlinger服务以及窗口管理策略类PhoneWindowManager交互,如图2所示。
图2 WindowManagerService服务与Activity窗口、SurfaceFlinger服务、PhoneWindowManager策略的关系图
在前面Android应用程序窗口(Activity)实现框架简要介绍和学习计划的一系列文章中,咱们已经分析过应用程序进程与WindowManagerService服务之间的交互过程了,所以,在这一系列文章中,咱们就将主要分析WindowManagerService服务的实现,以及它与SurfaceFlinger服务、PhoneWindowManager策略类的交互过程。
从整体上来看,WindowManagerService服务的实现是至关复杂的,例如,WindowManagerService类的核心成员函数performLayoutAndPlaceSurfacesLockedInner的代码有1200+行,比600-行代码的ViewRoot类的核心成员函数performTraversals还要恐怖。不过,WindowManagerService服务实现的复杂性是在预料之中的,毕竟它要管理的整个系统全部窗口的UI,而在任何一个系统中,窗口管理子系统都是极其复杂的。基于上述理由,采用硬碰硬的方式来分析WindowManagerService服务的实现是以卵击石,所以,这个系列的文章将对WindowManagerService服务进行分拆,而后再逐个击破,这是算法中的分而治之思想是一致的。
具体来讲,咱们将按照如下几个情景来分析WindowManagerService服务的实现:
2. 窗口的组织方式。
3. 输入法窗口的调整过程。
4. 壁纸窗口的调整过程。
5. 窗口Z轴位置的计算和调整过程。
7. Activity窗口的切换过程。
再次地,因为WindowManagerService服务的实现实在是太复杂,所以上述八个情景可能还不足于说明WindowManagerService服务的实现。若是出现这种状况,咱们在分析的过程当中会进行相应的调整。相信对WindowManagerService服务的实现进行分而治之的分析后,咱们就能够对Android系统的UI架构有一个深入的理解!敬请关注接下来的文章!