Wms作用
wms用于窗口的创建、添加、删除,同时可以控制窗口的层级
源码
关键类
DisplayThread
这个方法应该不算很关键,但是了解还是很有用的
wms 的创建中就必须在DisplayThread中进行
Session
Session.mUid, 这个mUid是什么,这个mUid其实是Linux系统分配给当前进程的id,这样可以方便我们的进程在跨进程通信中被识别。
wms的启动过程
- 既然是系统服务必然从SystemServer说起
- 在startOtherServices中初始化
- 获取wms实例并初始化
需要补充的是WMS.main方法最后一个参数把atms引用传如,所以atms和wms也是有关系的
- 看看wms.main 方法
下图中调用了DisplayThread.getHandler.runWithScissors来初始化wms,这说明wms的创建在这个位置是SystemServer中优先级最高的任务,必须等它创建完成才能执行
- WindowManagerService构造方法
- WindowManagerService.onInitReady方法初始化操作
第三步中调用了wm.onInitReady()方法进行初始化操作
initPolicy代码
扩展看一下runWithScissors方法
如果调用runWithScissors则说明runWithScissors内部的任务是优先级最高的,如果可以就要第一个执行。
小结:
wms主要用于窗口的创建,启动,删除等操作。wms是在SystemServer中启动的,他内部会持有多个系统服务,例如ams、atms、ims、dms等,并且在他创建成功后会马上被我们的ams引用,可见wms在应用页面展现的过程中是很重要的。
wms添加窗口
- 添加从wms.addWindow方法开始
下面两张图的判断逻辑我们可以不懂
如果token不为空,会执行下面的逻辑查看token是否合法
总结
wms.addWindow方法用添加一个Window,adWindow是一个跨进程调用,例如我们启动一个Activity就最终会调用到wms.addWindow方法。方法会传入会话Session和IWindow,其中Session一个应用只有一个,而IWindow定义在我们应用中的Binder对象实例。定义为ViewRootImpl.W类。在addWindow方法内部会帮我们处理很多添加window的逻辑。
在wms.addWindow中会对窗口的合法性进行校验,例如:重复添加window校验逻辑、判断窗口是否是一个子窗口。同时会获取合适的token(WindowToken),同时包括输入法的键盘、辅助服务事件执行、壁纸的逻辑、toast展示也都是在这里添加。
addWindow方法中的IWindow对象,最终会保存在WindowState类中。当wms需要操作我们的window的时候就会使用IWindow.asBinder来获取窗口对应的Binder对象来操作窗口,例如:
- IWindow.dispatchWindowShown 用来显示窗口
- IWindow.moved 窗口的移动
- IWindow.dispatchAppVisibility 判断应用是否是可见状态
- IWindow.resized 窗口尺寸重置
- IWindow.locationInParentDisplayChanged 窗口在父窗口中位置更改