banner
fwrite

fwrite

好好生活
twitter
github
email

WMS

WMS 全名是 WindowManagerService,它是客户端 APP 的管理者,处于 SystemServe r 进程,WMS 主要负责管理几件事情
窗口管理
负责 Window 添加、更新、删除,核心管理成员有 DisplayContentWindowTokenWindowState
窗口动画
Window 切换时,可以添加动画,让 Window 切换时更加自然,动画由 WMS 的动画子系统负责,该系统是 WindowAnimator
输入系统的中转
当使用者对视窗触控 or 输入时,都会触发 InputManagerService 会对触摸事件进行处理,将事件通过 WMS 传递到合适的窗口进行处理(这时 WMS 就是 中转站
Surface 管理
WMS 并不具备 Window 绘制的功能,每个 Window 都有一个 Surface 来绘制,而 WMS 负责 Surface 的分配

WMS 启动 - SystemServer#

WMS 是就是 WindowManagerService,它是系统服务,说到系统服务自然就会想到 SystemServer,那就让我们来看看 WMS 是如何被 SystemServer 唤起的
SystemServer 透过 WMS#main 方法启动
把 WMS 以Context#WINDOW_SERVICE window)设定到 ServiceManager 中
把启动的 WMS 对象设定给 AMS 服务

在 WMS 启动后会透过 onInitReadydisplayReadysystemReady 来完成 WMS 的后续动作(这些方法之后会介绍)

WMS - main 函数#

透过 DisplayThread 中的 Handler#runWithScissors 创建 WMS 对象(也就是创建 WMS 的线程与 SystemServer 线程不同)
Handler#runWithScissors 方法是透过锁来达成同步任务,保证该 Runnable 会先被 DisplayThread 的 Looper 先执行,执行完后才回到 SystemServer 的 Thread

HandlerThread - 创建 Looper#

DisplayThread - 创建 WMS 对象#

WMS 就是在 DisplayThread 类中被启动,DisplayThread 可以说是 WMS 的 MainThread
DisplayThread 可以创建安全 Handler,其主要功能是:处理 低延迟显示 的相关操作,并只能由 WindowManager、DisplayManager、InputManager 执行快速操作
从上面可以看到 DisplayThread 继承于 ServiceThread(而它继承于 HandlerThread),所以 它会在执行 run 方法时自动创建 Looper 对象,鉴于 HandlerThread 创建的 Handler 并不安全,所以 DisplayThread 这里自己创建 Handler(使用类锁)

传递事件给 WMS 有两种方式
直接呼叫 WMS function,即时传送

透过 DisplayThread 的 Looper 将事件丢入 WMS Thread(DisplayThread)中

UiThread 类#

UiThread 与 DisplayThread 差不多,但多添加了一个 dispose 方法,来停止 Looper,并结束该对象(置为 null),在 initPolicy()systemReady() 会使用到

AnimationThread 类#

AnimationThread 与 DisplayThread 差不多,但多添加了一个 dispose 方法,来停止 Looper,并结束该对象(置为 null)

SystemServer - WMS 启动后续#

WMS 创建#

前面有提到 WindowManagerService#main 方法会透过 DisplayThread(Thread)创建 WMS 的实例,在这里就会创建 H 类,而它的 Looper 就是当前 Thread 也就是 DisplayThread

WMS#onInitReady - 初始化 WindowManagerPolicy#

WMS#onInitReady 函数:取得 UiThread (另外一个 Thread) 的 Handler,并初始化 WindowManagerPolicy 实作呼叫 PhoneWindowManager#init 函数)

WMS#displayReady - 准备显示#

标示 WindowAnimator 初始化完成
重新配置设定,保证 DisplayWindowSettings 设定都有被正常使用
透过 ActivityTaskManager 来更新设置

WMS#systemReady - 服务准备完成#

WMS 重点#

窗口属性 - Layer Type#

Android 支持多种窗口,并且会将窗口分为三类,定义在 WindowManager#LayoutParams
Application Window:普通 App 应用就是使用以下窗口类型(列出几种举例),区间为 1 ~ 99 之间

Value名称说明
1FIRST_APPLICATION_WINDOW应用类视窗的起始值
1TYPE_BASE_APPLICATION其他应用都可覆盖在该 Window 之上
2TYPE_APPLICATION一般的应用窗口
3TYPE_APPLICATION_STARTING应用程序启动前的画面(用在加载某个画面之前的预前画面)
4TYPE_DRAWN_APPLICATION在绘画完成前等待
99LAST_APPLICATION_WINDOW应用视窗的结束值

Sub Window:附加在应用之上的视窗,一般称为 子窗口,其值区间为 1000 ~ 1999 之间

Value名称说明
1000FIRST_SUB_WINDOWSubWindow 的起始值
1000TYPE_APPLICATION_PANEL该 SubWindow 显示在依附的 App 之上
1001TYPE_APPLICATION_MEDIA显示有关 video 的 SubWindow
1002TYPE_APPLICATION_SUB_PANEL显示在依附的 app 之上,也在其他 SubWinow 之上
1003TYPE_APPLICATION_ATTACHED_DIALOGDialog 类型的 Window
1004TYPE_APPLICATION_MEDIA_OVERLAY显示在 TYPE_APPLICATION_MEDIA 还有底下的应用视窗之间
1005TYPE_APPLICATION_ABOVE_SUB_PANELTYPE_APPLICATION_SUB_PANEL 更上层的 Window
1999LAST_SUB_WINDOWSubWindow 的结束值

System Window:系统使用的 Window 视窗(以下列出几种),区间为 2000 ~ 2999 之间

Value名称说明
2000FIRST_SYSTEM_WINDOWSystem Window 的起始值
2001TYPE_STATUS_BARStatus bar 的 Window
2002TYPE_SEARCH_BAR搜寻 Bar 的 Window
2038TYPE_APPLICATION_OVERLAY覆盖于其他 Activity 视窗
2999LAST_SYSTEM_WINDOWSystem Window 的结束值

WindowState 初始化 - 决定 Base Layer#

从 WindState 构造函数可以知道,Base Laye r 数值可以从WindowManagerPolicy#getWindowLayerLw 方法取得

WindowManagerPolicy 透过传入的 WindowState 决定 Window 基础 Layer 层级(数值越高,越接近使用者 & 上层)

透过传入的WindowState决定 Window 基础 Layer 层级(数值越高,越接近使用者 & 上层)
WindowManagerPolicy#getSubWindowLayerFromTypeLw 方法:决定子窗口在父窗口中的偏移量

窗口属性 - LayoutParams#

Window 的统一属性设定在 WindowManager#LayoutParams中,并且有分为 typeFlags 两种设定
Type:上面已经说过,主要有分为 Application WindowSub WindowSystem Window 三种
Flag:莫认为 0,以下列出几个(有满多的)

ValueFlag说明
0x00000001FLAG_ALLOW_LOCK_WHILE_SCREEN_ON只要该窗口可见,就允许锁住屏幕(可配合 FLAG_KEEP_SCREEN_ON 使用)
0x00000002FLAG_DIM_BEHIND窗口后的 Window 都变淡
0x00000004FLAG_BLUR_BEHIND窗口后的 Window 变模糊
0x00000008FLAG_NOT_FOCUSABLE该 Window 视窗不可事件,事件会直接传递给后方 Window
0x00000010FLAG_NOT_TOUCHABLE该窗口不接受任何事件
0x00000080FLAG_KEEP_SCREEN_ON只要该窗口可见,就保持屏幕亮起

System UI 控制:System UI 的设定定义在 View 中,针对每个 View 个别设置

ValueFlag说明
0SYSTEM_UI_FLAG_VISIBLE设定 System UI 可见
0x00000002SYSTEM_UI_FLAG_HIDE_NAVIGATION设定 Navigtion Bar 不可见
0x00000004SYSTEM_UI_FLAG_FULLSCREEN屏幕全屏
0x00000100SYSTEM_UI_FLAG_LAYOUT_STABLE尽量保持 UI 布局的稳定性
0x00000400SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN从屏幕(0,0)开始绘制,也就是会从 Status Bar 开始绘制

WindowManagerService 简单理解起来是掌管该装置所有的 Window 的上下关系(z 轴的管理)、传输绘制任务到底层

变量说明补充
mPolicy : WindowManagerPolicy定义一个窗口策略所须遵循的 通用规范,并提供了 WindowManger 特定的 UI 行为WindowManager 是 interface,它的实作是 PhoneWindowManager
mSessions : ArraySet它主要用于进程通信,其他的应用进程的 View 想要和 WMS 通信,都要通过 Session 与 WMS 通信每个应用程序是透过 WindowManagerGlobal 取得 Session
mWindowMap : WindowHashMapWindowHashMap 继承 HashMap,用来保存所有 ViewImpl;Key: IBinder、Value: WindowStateKey 其实是 IWindow(ViewRootImpl 的内部类 W)、Value 是保存窗口信息
mFinishedStarting : ArrayListAppWindowToken 的父类是 WindowToken 当 APP 要向 WMS 申请一个新窗口时就要给予这个 token 让 WMS 验证每个 Activity 对应一个 AppWindowToken(一个 AppWindowToken 管理多个 WindowToken 视窗)
mResizingWindows : ArrayList用来存储正在调整大小的视窗
mAnimator : WindowAnimator管理 Window 动画 & 特效
mH : HH 是 Handler 类型,它是属于 DisplayThread Looper将消息给 WMS
mInputManager : InputManagerServiceIMS 系统服务,当使用者有输入讯息时,WMS 会给予一个适合的视窗
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.