android 进阶解密 第七章 理解WindowManager
1.WidowManager,Window,WMS之间的关系图
Window包含view并对view进行管理,Window是抽象概念,WindowManager用来管理Window,最终功能实现是在WMS中。
2.WindowManager关联类,如下图。
①.window和WindowManager通过setWindowManager关联。
②.ViewManager是一个接口,有addView,updateView,removeView三个方法,WindowManager继承这个接口,WindowManagerImpl实现这三个方法。具体功能的实现委托给WindowManagerGlobal类中,这里用到的是桥接模式。
③.WindowManagerGlobal是一个单例模式,一个进程就一个WindowManagerGlobal实例。
3.Window的属性
Window的属性很多,这里介绍与开发应用密切的3中,分别是Type(Window的类型)、Flag(Window的标识)、和SoftInputMode(软键盘的相关模式)
①.window的类型分成三大类:应用窗口类型(比如:应用窗口),子窗口(比如:PopupWindow)、系统窗口(比如:输入法窗口,Toast,系统音量条窗口,系统错误窗口)。
②.应用窗口的type值是1-99,子窗口的type值是1000-1999.系统窗口的type值是2000-2999。在一般情况下,Type值越大则Z-Oder越靠前,就是越靠近用户。
③.window的标志:
FLAG_NOT_FOCUSABLE:窗口不能获取焦点,也不能监听返回按钮。设置该标志的时候FLAG_NOT_TOUCHABLE也会被设置。
FLAG_NOT_TOUCHABLE:窗口不接受任何触摸事件。
FLAG_NOT_TOUCH_MODAL:将该窗口以外的触摸事件传递给其他window,而自己只会处理窗口区域内的事件。
FLAG_KEEP_SCREEN_ON:只要窗口可见,屏幕就一直亮着。
还有很多其他的flag,自己去体验哈
设置window的三种方式:
window.addFlags(内部调用的也是setFlags方法)
window.setFlags
windowManager.addView
④.软键盘相关的模式:
SOFT_INPUT_STATE_UNSPECIFIED:没有指定状态,系统会选择一个合适的状态或依赖于主题的设置。
SOFT_INPUT_STATE_UNCHANGED:不会改变软键盘状态。
SOFT_INPUT_STATE_HIDDEN:当用户进入该窗口是,软键盘默认隐藏。
SOFT_INPUT_STATE_ALWAYS_HIDDEN:当窗口获取焦点是,软键盘总是被隐藏。
SOFT_INPUT_ADJUST_RESIZE:当软键盘弹出时,窗口会调整大小。
SOFT_INPUT_ADJUST_PAN:当软键盘弹出时,窗口不需要调整大小,要确保输入焦点可见。
设置方式:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
4.Window的操作
Window中状态栏statusBar的添加过程时序图:
分析:
①.WindowManagerGlobal的addView方法中有三个列表参数:
View列表(ArrayList<View> mViews)、布局参数列表(ArrayList<WindowManager.LayoutParams> mParams)和ViewRootImpl列表(ArrayListM<ViewRootImpl> mRoots)
②.ViewRootImpl的职责:
View树的根并管理View树
触发View的测量、布局、绘制操作
输入事件的中转站
管理surface
负责与WMS进行通信
③.Activity的添加和上面的过程类似。在addView的时候添加的是decor。
④.Window的更新过程和添加过程类似,在ViewRootImpl的performTraversals方法中分别作了调用Session和WMS通信的relayoutWindow方法和测量(performMeasure)、布局(performLayout)、绘制(performDraw)