概述
Window表示一个窗口,在日常开发中很少直接接触Window,但是如果要做浮窗这样的效果就要用Window来实现。Window是一个抽象类,它的具体实现是PhoneWindow。创建Window,是通过WindowManager完成的。WindowManager是外界访问Window的入口,Window的具体创建、Window更新、销毁Window都是在WindowManagerService中完成的,而WindowManager和WindowManagerService之间是通过IPC通信来完成的(通信连接发生在ViewRootImpl中),因为WindowManagerService管理系统中所有Window,就像ActivityManagerServier管理系统中所有Activity一样。
先介绍下ViewRootImpl的作用
1:连接View和Window的桥梁
2:负责View的绘制流程、重绘流程的触发
3:负责UI线程安全检查工作
Window和WindowManager的使用
下面从一个简单例子说下WindowManager的用法
1:初始化WindowManager.LayoutParams
这个配置可以使Window显示在屏幕左上角位置处。WindowManager.LayoutParams的flags和type这两个参数很重要
Flag控制Window的显示属性
FLAG_NOT_FOCUSABLE
表示Window不需要获取焦点,也不需要接收各种输入事件,此标记会默认启动FLAG_NOT_TOUCH_MODAL
FLAG_NOT_TOUCH_MODAL
表示系统会将当前Window区域以外的点击事件传递给低层Window,当前Window区域内的事件自己处理,这个标记要开启,否则其他Window无法接收点击事件。
Type参数表示Window的类型。Window有三种类型,应用Window、子Window、系统Window。应用Window对应的是Activity。子Window不能单独存在,必须依附在其他Window上才能显示,比如常见Dialog。系统Window在创建时需要声明权限的,例如Toast系统状态栏都是系统Window。
Window的显示是分层,层次就是按照层级大小type来决定的,值大的显示在值小的Window上层。因此Activity对应的应用Window在最低层,Dialog显示在Activity的上层,而系统Window如Toast,自定义浮层会显示在Dialog上层。
2:显示和隐藏Window
3:更新Window的位置
Window的内部工作机制
对Window的操作,是通过WindowManager实现的,WindowManager继承ViewManager,
这是ViewManager中的所有方法,全部都是对View的操作,因此可以确定的是对Window的操作,实际上是对依附在其上的View的操作,从上面的例子中也证明了这一点。而View的显示必须依附在Window上,因此有View的地方肯定有Window,而连接View和Window的桥梁就是ViewRootImpl。下面通过Window的添加、更新、删除分析Window的内部工作原理。
创建Window
WindowManager的实现类是WindowManagerImpl,addView代码如下:
其直接调的的WindowManagerGlobal中的addView(),这是桥接设计模式,将具体实现委托给WindowManagerGlobal去实现。
WindowManagerGlobal中addView()中分为以下几步
1:检查参数合法性
2:初始化ViewRootImpl,并将View添加进列表
WindowManagerGlobal中有几个重要的集合用来存放Window相关数据。
mView存储Window对应的View;
mRoots存储Window对应的ViewRootImpl;
mParams存储Window的显示属性;
mDyingView用来存储将要被删除的Window对应的View;
在addView()中通过以下几步将Window相关的一系列对象添加进容器,至此ViewRootImpl的初始化就完成了,并将addView()流程传递到ViewRootImpl中,即setView();
3:在ViewRootImpl中更新View并完成Window的添加过程
在setView()中,会调用requestLayout(),完成View的绘制流程:
接着会调用IWindowSession通过IPC完成Window的添加过程
如此一来Window的添加请求就交给WindowManagerService去处理了,在WindowManagerService中会为会为每一个应用保存一个通信的Session。至此,Window的添加过程就结束了。
Window的更新和删除流程也是类似,在WindowManager中触发对Window的操作,最终执行在ViewRootImpl中,通过IPC最终在WindowManagerService中执行操作。
通过以上的流程分析,可见ViewRootImpl在View的绘制流程、Window的操作流程中的作用。
网友评论