WindowManager对Window进行管理,说到管理那就离不开对Window的添加、更新和删除的操作,在这里我们把它们统称为Window的操作。对于Window的操作,最终都是交由WMS来进行处理。窗口的操作分为两大部分,一部分是WindowManager处理部分,另一部分是WMS处理部分。我们知道Window分为三大类,分别是:Application Window(应用程序窗口)、Sub Windwow(子窗口)和System Window(系统窗口),对于不同类型的窗口添加过程会有所不同,但是对于WMS处理部分,添加的过程基本上是一样的, WMS对于这三大类的窗口基本是“一视同仁”的,而只是调用WindowManager的地方不同而已,如图所示:
首先介绍一下Activity,WindowManager,WMS之间的关系,如下图所示:
从上图中看到涉及到的基本概念为:先了解一下window windowmanger wms之间的关系如下:
从上图中看到,在Android开发中,Window是所有视图的载体,如Activity,Dialog和Toast的视图,我们想要对Window进行添加和删除就要通过WindowManager来操作,而WindowManager就是通过Binder与WindowManagerService进行跨进程通信,把具体的实现工作交给WindowManagerService,他们之间的类关系图如下:
5.1.2 Activity添加窗口的流程
Activity添加窗口的流程如下:
在ActivityThread的handleResumeActivity函数中会调用WindowManager的addView函数, 而这个WindowManager就是Activity的mWindowManager,代码如下所示:
从代码中看到当Activity满足条件时,调用ViewManager的addView来添加窗口,调用此方法需要传入两个参数,一个是需要添加的view,一个是WindowManager的LayoutParams参数,需要设置的参数一般会有flag,type,softInputMode.主要介绍如下:
Window的type代表添加窗口的类型
Window的Flag代表了窗口的显示特性
Window的输入法的模式
Statusbar,NavigationBar,已经分屏状态下的DividerView这些都属于系统的窗口,接下来分析一下添加NavigationBar与StatusBar的添加过程
5.2.1 添加NavigationBar
车载添加NavigationBar的流程如下:
如果是车载的设备,会执行到CarStatusBar的createNavigationBar的方法中,调用attachNavBarWindows方法来创建默认车机屏幕的NavigationBar,调用createNavigationBars来创建非默认屏的NavBar
attachNavBarWindows方法如下:
5.2.1 添加StatusBar
添加 statusbar的过程如下:调用CarStatusBar的start方法然后调用到StausBar的start方法后,接着调用createAddwindows后,就会调用到StatusBarWindowController的add方法添加window,代码如下:
一个Activity要添加一个Dialog窗口的,添加的方法可以如下:
创建dialog时传入的context为Activity的context,因此在调用dialog的show方法时,addwindow的parentWindow不为null,为acitivity在attach时创建的phonewindow
无论是哪种窗口最后都会调用到ViewRootImpl的setView的方法,最终通过session调用到wms的addWindow方法,两者关系如下:
5.4.1 何时创建ViewRootImpl对象
当所有的窗口添加调用WindowMangerGlobal的addview方法会创建ViewRootImpl代码如下:
5.4.2 ViewRootImpl调用setView方法
ViewRootImpl的setView的最终通过mWindowSession的addToDisplay方法最终调用到wms端,代码如下:
5.4.3 mWindowSession
这个mWindowSession是一个IWindowSession.AIDL接口类型,用来实现跨进程通信,在WMS内部会为每一个应用的请求保留一个单独的Session,同样实现了IWindowSession接口,应用与WMS之间的通信就通过这个Session。mWindowSession是在viewRootImpl构造函数中被赋值的
mWindowSession是通过WindowManagerGlobal的单例类的getWindowSession()获得的代码如下:
此段代码主要执行了通过getWindowManagerService方法来获得WindowManagerService的在本地应用中的代理,通过WMS的本地代理的openSession来获取Session。代码如下:
当第一次点击一个应用,此时启动的方式为冷启动会启动一个startingWindow,之后会添加真正的Activity的窗口,对应的堆栈如下:
启动startingWindow的:
wms端添加窗口的:
WMS端添加其他窗口的:
addwindow方法主要执行的功能为:
1. 对所要添加的窗口进行检查,如果窗口不满足一些条件,就不会再执行下面的代码逻辑。
2. WindowToken相关的处理,比如有的窗口类型需要提供WindowToken,没有提供的话就不会执行下面的代码逻辑,有的窗口类型则需要由WMS隐式创建WindowToken。
3. WindowState的创建和相关处理,将WindowToken和WindowState相关联。
4. 创建和配置DisplayContent,完成窗口添加到系统前的准备工作。