一、功能

窗体管理是ANDROID框架一个重要部分,主要包含例如以下功能:

(1)Z-ordered的维护

   (2)窗体的创建、销毁

   (3)窗体的绘制、布局

(4)Token管理,AppToken

(5)活动窗体管理(FocusWindow)

(6)活动应用管理(FocusAPP)

(7)输入法管理

(8)系统消息收集与分发

这些功能主要由一个窗体管理服务和对应的client来实现的,client通过BINDER机制与服务实现交互。

      窗体管理服务端负责基本的窗体管理功能,由一个WindowManagerService服务及相关的类来组成。

client则负责与窗体管理服务交互,并相应用和其他服务提供窗体管理接口,包含提供窗体视图的加入、移出和更新等接口函数。client的功能通过WindowManager接口及事实上现WindowManagerImpl和相关类来完毕。WindowManager提供的接口函数包含例如以下几个:

1、 public
voidaddView(View view, ViewGroup.LayoutParams params)。

用来在窗体实例相应的窗体上加入一个视图。

2、public
void removeView(View view) 。

用来从窗体实例相应的窗体上移出一个视图。

3、public
void updateViewLayout(View view,ViewGroup.LayoutParams params);

用来更新窗体上的视图的布局。

4、   public
DisplaygetDefaultDisplay();

每一个窗体管理实例须要绑定到特定的显示对象上,并在此显示对象上创建和显示新的窗体。

该函数返回一个窗体管理实例管理和使用的显示对象。

窗体为了能在另外的显示器上显示,须要先调用Context.createDisplayContext创建一个显示对象使用的独立的Context,然后使用该Context调用Context.getSystemService(Context.WINDOW_SERVICE)函数获得该显示对象相应的窗体管理实例。也能够直接创建一个Presentation对象,Presentation对象会自己主动创建显示对象须要的窗体管理实例和Context对象。

二、类图

窗体管理的整个类图例如以下:

整个类图包含client和服务端两大部分。

服务端的主要类有WindowManagerService、Session、WindowState、WindowToken、AppWindowToken、DisplayContent等主要类。

WindowManagerService服务是一个系统服务类。是整个窗体管理机制实现的核心。

Session对象也是一个服务端的桩对象。用来为client提供交互接口(IWindowSession)。包含窗体的创建、销毁、布局等接口。

每一个与窗体管理服务交互的进程通常都须要打开一个Session对象来实现交互。用来保证一个Session会话期间窗体状态的一致。

Session对象在一个进程新建第一个视图时使用窗体管理服务的的openSession接口函数创建,第一个视图新建期间也创建一个SurfaceSession对象用来实现视图的绘制操作。SurfaceSession对象用来与SurfaceFliger服务建立连接,实现视图及包括的子视图在显示硬件上的实际输出工作。

服务端创建的窗体类型包含三大类型的窗体:包含三种类型的应用窗体、五种类型的子窗体(必须依附于其他窗体的窗体类型,31种系统窗体(系统创建的窗体,应用不能使用)。

应用窗体类型:

  1. TYPE_BASE_APPLICATION

    基窗体。作为全部其他应用窗体的基窗体,全部其他应用窗体须要在该类型的窗体上面呈现。

  2. TYPE_APPLICATION

    普通应用窗体,通常与一个ACTIVITY相应,该类型的应用窗体必须有一个Activity
    token来标示它所属的Activity。

  3. TYPE_APPLICATION_STARTING

    应用启动窗体,该类型窗体在应用启动时显示。

    该类型窗体由系统使用。用来在应用可以显示本身窗体之前显示一些其他内容。

子窗体类型:

  1. TYPE_APPLICATION_PANEL

    PANEL类型窗体。用来在它所依附的应用窗体上面显示一个PANEL。

  2. TYPE_APPLICATION_MEDIA

    MEDIA窗体,这样的类型的子窗体在它所依附应用窗体的后面显示,用来显示媒体内容,如视频。

  3. TYPE_APPLICATION_SUB_PANEL

    子PANEL窗体,该类型的窗体在它所依附的应用窗体和随意的PANEL窗体的上面显示。

  4. TYPE_APPLICATION_ATTACHED_DIALOG

    依附对话框窗体,用来在一个应用窗体上显示一个对话框。

  5. TYPE_APPLICATION_MEDIA_OVERLAY

    媒体覆盖窗体。用来在媒体窗体上显示一些覆盖物,该类型窗体在应用窗体和媒体窗体之间显示。因此它应该是透明的。

系统窗体类型包含:TYPE_STATUS_BAR、TYPE_SEARCH_BAR、TYPE_PHONE、TYPE_SYSTEM_ALERT、TYPE_KEYGUARD、TYPE_TOAST、TYPE_SYSTEM_OVERLAY、TYPE_PRIORITY_PHONE、TYPE_SYSTEM_DIALOG、TYPE_KEYGUARD_DIALOG、TYPE_SYSTEM_ERROR、TYPE_INPUT_METHOD、TYPE_INPUT_METHOD_DIALOG、TYPE_WALLPAPER、TYPE_STATUS_BAR_PANEL、TYPE_SECURE_SYSTEM_OVERLAY、TYPE_DRAG、TYPE_STATUS_BAR_SUB_PANEL、TYPE_POINTER、TYPE_NAVIGATION_BAR、TYPE_VOLUME_OVERLAY、TYPE_BOOT_PROGRESS、TYPE_HIDDEN_NAV_CONSUMER、TYPE_DREAM、TYPE_NAVIGATION_BAR_PANEL、TYPE_UNIVERSE_BACKGROUND、TYPE_DISPLAY_OVERLAY、TYPE_MAGNIFICATION_OVERLAY、TYPE_RECENTS_OVERLAY、TYPE_KEYGUARD_SCRIM、TYPE_PRIVATE_PRESENTATION。

窗体管理服务内部使用WindowState窗体状态对象来维护每一种类型的窗体状态。并使用WindowToken对象来唯一标示每一个窗体,因此每一个窗体必须相应一个WindowToken对象和一个WindowState对象,每一个窗体相应的WindowToken对象依据client传送的窗体布局參数中的token值来实例化和定位。

在窗体管理服务的addWindow函数中,使用attrs.token作为參数实例化一个WindowToken对象。并使用token作为键值保存到窗体管理服务的一个HashMap变量中。

<span style="color:#000066;">   mTokenMap.put(attrs.token, WindoToken); </span>

每一个WindowState窗体状态对象也依据传进来的client对象(为一个IWindow.Stub对象)作为键值放到mWindowMap中。实现WindowState窗体状态对象与client对象的绑定。

<span style="color:#000066;">        mWindowMap.put(client.asBinder(), win);

        finalArrayList<WindowState> mWindows;mWindowMap.put(client.asBinder(), win);
</span>


attrs
.token參数是窗体布局參数中LayoutParams的一个binder对象,在client新建窗体(addView)时赋值,主窗体类型相应ACTIVITY的AppToken。子窗体类型相应主视图的WindowToken。

<span style="color:#000066;">	public static class LayoutParams extends ViewGroup.LayoutParams  

	       implements Parcelable {  

	        public int type;

	       public IBinder token = null;  

	 }
</span>

窗体管理系统支持多用户以及在多个显示器进行输出,不同的用户能够显示不同的内容。不同的显示器也能够显示不同的内容。并且每个窗体还能够依附有子窗体。

因此每个WindowState对象维护一个独立的DisplayContent对象用来指示相应的窗体所依附的显示单元,每个DisplayContent对象内部也维护一个WindowState类型的WindowList窗体列表,用来存储该显示单元要显示的窗体列表。DisplayContent对象还通过StackBox、TaskStack及Task等对象或对象数组来管理该显示单元上要显示的应用活动窗体。

AppWindowToken对象是WindowToken类的特例。用来作为应用窗体类型的标示。应用类型的窗体相应的WindowToken对象的appWindowToken属性必须指向一个AppWindowToken对象。

AppWindowToken对象内部还包括一个与client的应用窗体交互的IApplicationToken接口,实现与Activity的交互。

窗体管理系统中的ViewServer类提供了窗体的远端控制功能。

InputMonitor类提供了输入焦点窗体的监视和输入提交到对应窗体的功能。

窗体管理系统还提供了一个WindowManagerPolicy类,
窗体管理服务通过WindowManagerPolicy类实现窗体管理须要的全部UI方面的特定行为和操作(如窗体布局、特定的窗体类型、按键提交等)。

窗体管理服务还通过IActivityManager、DisplayManager、DisplayManagerService、InputManagerService、IInputMethodManager等接口和对象与活动管理服务、显示管理服务、输入管理服务、输入法管理服务交互。

client主要包括四个类 : ViewRootImpl、WindowManagerImpl、VIEW、Surface。

ViewRootImpl是视图处理类。是client视图的处理类,client的视图通过该类与窗体管理服务交互,因此ViewRootImpl是一个中介类。

ViewRootImpl内部包括一个从IWindow.Stub派生的内部类(ViewRootImpl.W)。窗体管理服务通过该对象能够与client反向通讯。

client与窗体服务打开的会话保存在一个IWindowSession类型的变量中。client使用该变量向窗体管理服务端的Session对象发送请求,窗体管理服务中的窗体状态对象使用IWindow接口向client回送应答,借助ViewRootImpl的这两个Binder对象实现了client与窗体管理服务端的双向交互。

ViewRootImpl对象还维护一个View对象和一个View对象关联的View.AttachInfo类型的对象。ViewRootImpl通过这两个对象实现视图的绘制等功能。

ViewRootImpl还与Surface类关联。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvR29vSG9uZw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">

WindowManagerImpl是clientWindowManager管理接口的实现,WindowManagerImpl内部维护一个单例的WindowManagerGlobal对象。WindowManagerImpl通过该对象转发client的窗体管理请求。WindowManagerGlobal对象内部维护一个ViewRootImpl实例数组和一个View视图对象数组,每次client加入一个视图时都新创建一个ViewRootImpl对象,并把要加入的视图和新创建的ViewRootImpl对象加入到对应数组中,并调用新创建的ViewRootImpl对象的setView函数。

View类是视图的基类。实现视图的基本功能。如绘制等。View.AttachInfo是View类的内部类,用来维护视图的相关信息。视图的主视图通过ViewRootImpl对象与窗体管理服务交互,加入绑定到特定的显示桌面和窗体,ViewRootImpl也实现了ViewParent接口。因此也作为主视图的父视图使用。

Surface类用来提供视图复合输出的显示画布。

以下是一个打开一个窗体的序列图:

1)client在创建窗体时首先调用getWindowManager获得本地窗体管理对象,并调用其addView函数,在这里还为窗体的布局參数赋值,如窗体标题、包名字、token值、flag值等;

2)WindowManagerImpl是WindowManage的详细实现,因此窗体管理接口的addView函数实际调用WindowManagerImpl的addView函数;

4)WindowManagerImpl的addView函数首先查看要加入的视图是否已经存在,若不存在则实例化一个ViewRootImpl对象。并把view和ViewRootImpl对象及布局參数保存到本地数组中。接着调用ViewRootImpl对象的setView函数;

5)ViewRootImpl对象的setView函数先请求进行窗体的布局(调用requestLayout。在client完毕一些处理后,也终于通过IWindowSession向窗体管理服务端的Session对象发送relayout布局请求),然后依据窗体属性是否支持输入实例化一个InputChannel,然后通过服务端远程代理对象IWindowSession向服务端Session对象发送新建窗体的请求(调用其addToDisplay接口)。最后还要调用assignParent函数设置视图的父视图为ViewRootImpl对象本身;

6)服务端的Session对象收到addToDisplay请求后,就调用窗体管理服务的addWindow函数来完毕新建窗体的任务,完毕实际创建窗体的工作。addWindow中首先实例化一个WindowState对象代表新建的窗体,接着使用client窗体的Binder对象(ViewRootImpl.W对象)为键值把WindowState对象放入mWindowMap中,并依据Z-ORDER放入WindowState所维护的窗体列表数组中,还要调用WindowState对象的attach函数与Session完毕绑定。并在SurfaceSession没有创建时完毕创建;然后新建或获得WindowToken。并使用传进来的client窗体布局參数中的token值把WindowToken放入mTokenMap中,建立两者的映射关系。最后依据窗体是否能可以接收键值更新焦点窗体。

版权全部。请转载时清楚注明链接和出处,谢谢!



ANDROID窗体管理服务实现机制和架构分析的更多相关文章

  1. ANDROID窗口管理服务实现机制和架构分析

     一.功能 窗口管理是ANDROID框架一个重要部分,主要包括如下功能: )Z-ordered的维护 )窗口的创建.销毁 )窗口的绘制.布局 )Token管理,AppToken )活动窗口管理(F ...

  2. Android窗口管理服务WindowManagerService计算窗口Z轴位置的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8570428 通过前面几篇文章的学习,我们知道了 ...

  3. Android窗口管理服务WindowManagerService显示Activity组件的启动窗口(Starting Window)的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8577789 在Android系统中,Activ ...

  4. Android窗口管理服务WindowManagerService显示窗口动画的原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8611754 在前一文中,我们分析了Activi ...

  5. Android窗口管理服务WindowManagerService切换Activity窗口(App Transition)的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8596449 在Android系统中,同一时刻只 ...

  6. Android窗口管理服务WindowManagerService对壁纸窗口(Wallpaper Window)的管理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8550820 Android系统中,壁纸窗口和输 ...

  7. Android窗口管理服务WindowManagerService对输入法窗口(Input Method Window)的管理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8526644 在Android系统中,输入法窗口 ...

  8. Android 输入管理服务-输入事件到达之后的处理流程

    接上一篇博客"Android 输入管理服务启动过程的流程".这两天分析了Android 输入管理服务接收到输入事件之后的处理流程,详细流程例如以下面两图所看到的: 接下图

  9. Android窗口管理服务WindowManagerService的简要介绍和学习计划

    在前一个系列文章中,我们从个体的角度来分析了Android应用程序窗口的实现框架.事实上,如果我们从整体的角度来看,Android应用程序窗口的 实现要更复杂,因为它们的类型和作用不同,且会相互影响. ...

随机推荐

  1. [转]Linux之ACL权限

    转自:http://www.2cto.com/os/201110/108736.html 引言 前面的内容中,我们讲到传统的权限仅有三种身份(owner,group,others)搭配三种权限(r,w ...

  2. vs项目结构解析

    当我们用VS开发一个项目的时候,首先应该清楚用VS这个IDE生成的一些文件和文件夹是什么意思,起什么作用,什么场合下使用. 因为我使用的是VS2015,就以这个为例来进行一些说明: 首先要做的是更改你 ...

  3. 【1】Jdk1.8中的HashMap实现原理

    HashMap概述 HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 内部实现 ...

  4. Paint、Canvas

    1.Canvas类 public class Canvas { public static final int ALL_SAVE_FLAG = 31; /** @deprecated */ @Depr ...

  5. 获取Google地图位置坐标并嵌入到网页

    有时候做网页的时候,可能需要一个地图显示,可能会用到Google地图,所以就分享一下get到的新技能.在网上查资料的时候有这种方式 但是我没做成功,所以找了其他的方式. 首先,打开Google地图,查 ...

  6. 重现apache commons fileupload DOS漏洞

    这个漏洞是2014年2月4日被发现的, 因为该组件试用范围非常广, 所以该漏洞的影响也非常巨大.通过特制的包含畸形header的http请求,可以导致使用该组件的应用程序进入无限循环从而耗尽CPU等资 ...

  7. centos7下手动制作trove镜像

    获取镜像 [root@bldattet1 ~]#  wget http://mirrors.aliyun.com/centos/7.5.1804/isos/x86_64/CentOS-7-x86_64 ...

  8. Dispatch Queues 线程池

    Dispatch Queues Dispatch queues are a C-based mechanism for executing custom tasks. A dispatch queue ...

  9. 奇怪的print progname ":\n"日志

    [root@xxxxxxxx /home/ahao.mah] #tail /var/log/messages -f Feb 10 10:01:01 csaccurate-49-5011 } Feb 1 ...

  10. sudo dpkg-reconfigure phpmyadmin命令,重新配置一遍phpmyadmin

    sudo dpkg-reconfigure phpmyadmin命令,重新配置一遍phpmyadmin