美文网首页
理解Window和WindowManager

理解Window和WindowManager

作者: HopeMan | 来源:发表于2019-08-23 08:48 被阅读0次

    概述

            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的操作流程中的作用。

    相关文章

      网友评论

          本文标题:理解Window和WindowManager

          本文链接:https://www.haomeiwen.com/subject/efwnsctx.html