一 WMS的职责
1 窗口管理
WMS是窗口的管理者,它复杂窗口的启动、添加和删除,另外窗口的大小和层级也是由WMS进行管理的
窗口管理的核心成员有DisplayContent、WindowToken和WindowState
2 窗口动画
窗口间进行切换时,使用窗口动画更炫一些,窗口动画由WMS的动画子系统来负责,动画子系统的管理者为WindowAnimator
3 输入系统的中转站
通过对窗口的触摸从而产生触摸事件,InputManagerService(IMS)会对触摸事件进行处理,它会寻找一个最合适的窗口来处理触摸反馈信息,WMS是窗口的管理者,它作为输入系统中转站再合适不过了
4 surface管理
窗口并不具备绘制功能,因此每个窗口都需要一块surface来供自己绘制,为每个窗口分配Surface是由WMS来完成的
二 WMS的创建过程
WMS是在SystemServer进程中创建的
D:\android_code\base\services\java\com\android\server\SystemServer.java
首先在SystemServer中调用main方法,main方法中调用了SystemServer的run方法
在run方法中,加载了动态库,创建了SystemServiceManager,启动引导服务、核心服务和其他服务
引导服务:startBootstrapServices方法,用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务
核心服务:startCoreServices方法,启动了DropBoxManagerService、BatteryService、UsageStatsService和WebViewUpdateService.
其他服务:startOtherServices方法,启动了CameraService、AlarmManagerService、VrManagerService,WMS等服务
这些服务的父类都是SystemService
其中其他服务是一些非紧要和不需要立即启动的服务,WMS就是其中一种
在 startOtherServices方法中,先是得到Watchdog实例并对它进行初始化,Watchdog用于监控系统的一些关键服务的运行状况,然后创建IMS,并赋值给IMS类型的inputManager对象。
然后执行WMS的main方法,其内部会创建WMS,main方法中传入了IMS,WMS是输入事件的中转站,其内部包含IMS的引用
WMS的main方法时运行在SystemServer的run方法中,换句话说就是运行在"system_server"线程中
然后将WMS和IMS注册到ServiceManager中,这样如果某个客户端想要使用WMS,就需要先去ServiceManager中查询信息,然后根据信息与WMS所在的进程建立通信通路,客户端就可以使用WMS了
最后初始化屏幕显示信息,然后通知WMS,系统的初始化工作已经完成,内部调用了WindManagerPolicy的systemReady方法
然后看看WMS的main方法
D:\android_code\base\services\core\java\com\android\server\wm\WindowManagerService.java
首先调用了DisplayThread的getHandler方法,用来得到DisplayThread的Handler实例,DisplayThread是一个单例的前台线程
这个线程用来处理需要低延时显示的相关操作,然后调用runWithScissors方法,创建了WMS的实例,这个过程运行在Runnable的run方法中,而Runnable则传到了DisplayThread对于handler的runWithScissors方法中,说明WMS的创建时运行在android.display线程中的,
然后看下runWithScissors方法
D:\android_code\base\core\java\android\os\Handler.java
根据每个线程只有一个Looper的原理来判断当前的线程(system_server线程)是否是Handler所指向的线程(android.display线程)如果是则直接之间Runnable的run方法,如果不是则调用BlockingRunnable的postAndWait方法,并将当前线程的Runnable作为参数传进去,BlockingRunnable是handler的内部类
将当前的BlockingRunnable添加到handler的任务队列中。timeOut是runWithScissors中带入的参数为0,如果mDone为false的话,会一直调用wait方法使得当前线程(system_server线程)进入等待状态,system_server等待的就是android.display线程,一直到android.display线程执行完毕后再执行 system_server线程,这是因为android.display线程内部执行了WMS的创建,而WMS的创建优先级更高
然后看看WMS的构造方法
D:\android_code\base\services\core\java\com\android\server\wm\WindowManagerService.java
先是保存IMS,这样WMS就持有IMS的引用,然后获得Display数组,封装成DisplayContent,DisplayContent用来描述一块屏幕。
然后获得AMS实例,并赋值给mActivityManager,这样WMS就持有AMS的引用。
然后创建WindowAnimator,它用来管理所有的窗口动画。
然后初始化窗口管理策略的接口类WindowManagerPolicy,它用来定义一个窗口策略索要遵循的通用规范
然后将自身也就是WMS通过addMonitor添加到Watchdog中,Watchdog用来监控系统的一些关键服务的运行状况,这些监控的服务都要事先Watchdog.Monitor接口。Watchdog每分钟都会对被监控的系统服务进行检查,如果被监控的系统服务出现了死锁,则会杀死Watchdog所在的进程,也就是SystemServer进程
看看initPolicy方法
先是执行了WMP的init方法,WMP是一个接口,init方法具体事先是在PhoneWindowManager中实现
PWM的init方法运行在android.ui线程中,它的优先级高于initPolicy所在的android.display线程。因此android.display线程
要等PWM的init方法执行完毕后,处于等待状态的android.display线程才会被唤醒从而继续执行下面的代码
System_server、android.display、android.ui线程之间的关系
1 首先在system_server线程中执行了SystemServer的startOtherSevices方法,在startOtherSevices方法中调用了WMS的main方法,main方法会创建WMS,创建的过程是在android.display线程中实现的,创建WMS的优先级更高 ,因此system_server线程要等WMS创建完成后,处于等待状态的system_server线程才会被唤醒从而继续执行下面的代码
2 在WMS的构造方法中会调用WMS的initPolicy方法,在initPolicy方法中又会调用PWM的init方法,PWM的init方法在android.ui线程中运行的,它的优先级高于android.display线程,因此android.display线程线程要等PWM的init方法执行完毕后,处于等待状态的android.display线程才会被唤醒从而继续执行下面的代码
3 PWM的init方法执行完毕后,android.display线程就完成了WMS的创建,等待的system_server线程被唤醒后继续执行WMS的main方法后面的代码逻辑,比如WMS的displayReady方法用来初始化屏幕显示信息