3. Z-order顺序管理
4. 焦点窗口和焦点应用的管理
5. 输入法窗口管理和墙纸窗口管理
6. 转场动画
7. 系统消息收集和分发
服务端的实现代码是在/framework/base/services/java/com/android/server/wm/里,核心的几个类是:
WindowManagerService.java
WindowState.java
WindowToken.java
AppWindowToken.java
Session.java
InputManager.java
InputMonitor.java
类解释:
WindowManagerService负责完成窗口的管理工作;
WindowState和客户端窗口一一对应,应用调用WindowManager.addView()时,最终会在WindowManagerService添加一个WindowState与之一一对应。
WindowToken是一个句柄,保存了所有具有同一个token的WindowState。应用请求WindowManagerService添加窗口的时候,提供了一个token,该token标识了被添加窗口的归属,WindowManagerService为该token生成一个WindowToken对象,所有token相同的WindowState被关联到同一个WindowToken。如输入法添加窗口时,会传递一个mCurrToken,墙纸服务添加窗口时,会传递一个newConn.mToken。
AppWindowToken继承于WindowToken,专门用于标识一个Activity。AppWindowToken里的token实际上就是指向了一个Activity。ActivityManagerService通知应用启动的时候,在服务端生成一个token用于标识该Activity,并且把该token传递到应用客户端,客户端的Activity在申请添加窗口时,以该token作为标识传递到WindowManagerService。同一个Activity中的主窗口、对话框窗口、菜单窗口都关联到同一个AppWindowToken。
Session表示一个客户端和服务端的交互会话。一般来说不同的应用通过不同的会话来和WindowManagerService交互,但是处于同一个进程的不同应用通过同一个Session来交互。
InputManager和InputMonitor负责上层的消息分发功能。
WindowManagerService内部的几个重要成员变量:
ArrayList mWindows
HashMap<IBinder, WindowState> mWindowMap
ArrayList mTokenList
ArrayList mAppTokens
mWindows保存了系统中所有的WindowState;
mWindowMap保存了每个WindowState和客户端窗口的映射关系,客户端应用请求窗口操作时,通过mWindowMap查询到对应的WindowState;
mTokenList保存了所有的WindowToken
mAppTokens保存了所有的AppWindowToken
窗口管理服务端主要类图
一个Activity从启动到添加窗口的整个流程如下:
ActivityManagerService在接收到启动Activity请求时,首先生成一个token作为该Activity的唯一标识。然后调用WindowManagerService向其添加一个AppWindowToken,此AppWindowToken封装了Activity的token。接着AMS启动应用客户端进程并把token传递到该进程,在客户端进程里完成Activity的初始化。在Activity的attach()函数中,Activity完成PhoneWindow的创建,并且把token传递给PhoneWindow。在Activity调用WindowManager.addView()时,在WindowManager内部会把token和该View关联,真正向WindowManagerService申请创建窗口的时候,再把token传递给WindowManagerService。WindowManagerService接收到创建窗口的请求的时候,通过mTokenMap查询对应该token的AppWindowToken,如果为空则抛出异常,否则创建一个WindowState并完成初始化工作和其他数据结构的调整工作。在这个过程中,token贯穿了服务端的AMS、WMS和客户端的Activity、Window。
Activity启动过程中创建窗口的时序图
四、 WMS中服务端和客户端的交互接口和数据结构
应用请求创建窗口时,和应用直接交互的是WindowManager对象。WindowManager只是一个接口,调用addView()创建窗口时正真交互的是WindowManagerImpl对象。WindowManagerImpl管理单个应用的所有本地窗口。应用调用addView()创建窗口时,WindowManagerImpl会生成一个ViewRoot对象与之相对应,并且把相应的参数LayoutParams保存起来。
addView()的执行流程如下:
(1) 检查所添加的窗口是否已经添加过,不允许重复添加;
(2) 如果所添加窗口为子窗口类型,找到其父窗口,并保存在内部变量中;
(3) 创建一个新的ViewRoot,并保存对应的View(DecorView)和LayoutParams;
(4) 调用ViewRoot的setView()方法,完成真正意义上的添加工作。
ViewRoot本质上是一个Handler,并且实现了ViewParent接口。ViewRoot的主要功能是:
1. 负责分发消息事件,如Key、Motion事件等;
2. 负责和WMS的交互,分发WMS的交互命令;
3. 作为DecorView的parent,对DecorView进行draw、measure、layout等操作;
在addView()的第3、4步完成之后,ViewRoot就全权接管了和WMS的交互工作,DecorView不需要做任何交互动作。ViewRoot和WMS之间的双向对话,主要是通过以下两个数据结构进行的:
IWindowSession
IWindow
这两个数据结构都是标准的aidl接口,用于进程之间的同步通信。IWindowSession负责ViewRoot到WMS的单向请求,IWindow则用于WMS回调ViewRoot。在ViewRoot对象内部,存在着一个IWindowSession的静态成员和一个IWindow的非静态成员,所以一个进程里只有一个IWindowSession对象,但是可以有多个IWindow对象。
Window、WindowManager、DecorView、ViewRoot、IWindowSession、IWindowSession、WindowState、WindowManagerService之间的关系可用下图来表示:
在ViewRoot的构造函数中,调用getWindowSession()初始化静态成员sWindowSession和非静态成员mWindow。在第4步调用setView()方法时,ViewRoot会调用sWindowSession.add()方法,把IWindow添加到WMS中,WMS就会生成一个WindowState与之一一对应,并且把IWindow对象保存到WindowState内部作为回调的接口。之后所有WMS的命令,都会通过直接访问IWindow接口,以消息的形式分发到ViewRoot,ViewRoot来完成相应的处理,或对DecorView进行操作,或完成后通过sWindowSession报告给WMS。
一个窗口从添加到显示可用以下时序图表示:
窗口添加过程时序图
到此为止,整个窗口管理系统整体架构可表示如下:
窗口管理系统整体架构图
五、 WindowState和Surface
从Client端调用WindowManager的addView()方法到WMS完成WindowState的初始化,在这整个过程中,只是完成了一个窗口数据结构的创建,也就是说,到现在为止,Client端的窗口和Server端的窗口已经建立了一种相对固定的连接关系,并且Client端和Server端之间能够正常通信,WMS能够透明的对Client端的窗口进行操作,同时WMS也能够接收Client端窗口的命令,对WindowState进行相应的调整。
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
-1715485114463)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!