美文网首页
Android 窗口机制

Android 窗口机制

作者: 牛晓伟 | 来源:发表于2018-02-10 19:20 被阅读246次

    本文章主要是分析android中View,Window,WindowManager,WindowManagerService之间的关系

    c/s分析窗口机制

    先看一个类图


    image.png

    在来看张c与s通信的图


    ViewRootImpl与WindowManagerService通信

    根据上面的图我们来分析下:
    类的作用:
    ViewRootImpl
    这个类实在是太重要了,它是整个view tree的最最顶级类,当调用WindowManagerGlobal.get().addView方法的时候,这时候被add的view就会创建一个ViewRootImpl的实例,该实例会保存被add的view

    mWIndowSession这是它的属性,它是被WindowManagerGlobal创建的,它是在整个进程中只有唯一的一个实例,它是ViewRootImpl给WindowManagerService发送命令的桥接者

    mWindow是一个W类型的属性,W继承了IWindow.Stub,该类的作用是WindowManagerService给ViewRootImpl发送命令的桥接者

    setView方法会通过mWindowession把mWindow添加到WindowManagerService中,这样它们就建立了联系。同时进行各种其他处理,其中会调用requestLayout方法,该方法会进行mView的绘制流程,measure,layout,draw

    它就相当于c/s模式中的c,s给它发送的信息,一些自己处理,一些会交给mView来处理,WindowInputEventReceiver是它的一个内部类,该类作用是接收touch事件,然后把touch事件交给mView进行分发

    WindowManagerGlobal
    它在整个进程只存在唯一的一个实例,它会管理该进程中add的所有view,并且给每个add的view生成自己的ViewRootImpl,保存view的layoutParams参数,比如当activity或dialog销毁的时候调用removeView方法把view给移除掉

    sWindowSession是IWindowSession的实例,会调用WindowManagerService的openSession方法创建它,它是整个进程中唯一的一个实例

    该类有点门面模式的意思,它管理了整个进程所add的view

    WindowManagerService
    它管理了所有进程的window,现在只是暂时对该类有一个浅显的了解,不敢多说

    IWindow
    它是WindowManagerService给ViewRootImpl发送命令的桥接者,同时它与ViewRootImpl是一一对应关系,使用弱引用的方式持有ViewRootImpl实例,WindowManagerService给ViewRootImpl发送命令,会调用ViewRootImpl的方法,通过ui Handler来调用最终的方法

    因此ViewRootImpl相当于c,WindowManagerService相当于s

    Window,PhoneWindow,WindowManager,WindowManagerImpl关系

    先看类图


    image.png

    上面的类图展示了这四个类之间的一个关系
    那我们先来看段代码

        WindowManager wm = context.getSystemService(Context.WINDOW_SERVICE);
    

    这段代码大家肯定很熟悉,其实最终得到的对象是WindowManagerImpl类型的,再来看段代码

        wm.addView(view,lp);
    

    上面的代码是创建一个特殊的window,该window可以悬浮在所有view的上面,我们只能通过WindowManager添加window,是完全不可以通过生成一个Window的实例,然后把该实例添加到WIndowManager中的

    来看下各类的作用
    WIndowManagerImpl
    它实现了WIndowManager和ViewManager,可以理解它为本地的一个Window服务

    mGlobal属性,它是WindowManagerGlobal类型的

    addView方法,该方法最终会调用mGlobal.addView,关于该过程上面已经分析过了

    同理其他的方法也会调用WindowManagerGlobal里面的方法

    在addView的时候,根据LayoutParams的不同来显示不同的window,LayoutParams继承了ViewGroup.LayoutParams

    在创建Activity或Service或其他的组件时,都会生成自己的WindowManager实例

    Window
    可以理解为是封装了title的显示area,background,及key,touch 等事件的处理过程的类,它就是一个封装包裹类,它自己并不会进行绘制等流程。

    Callback定义了一些事件处理等的协议,这样Window的拥有者就可以知道当前发生了哪些事件

    PhoneWindow
    它继承了Window,当然了它是通过一个策略模式类生成的,使用策略模式生成应该是为了扩展考虑

    DecorView 是PhoneWindow的内部类,它继承了FrameLayout,是整个view tree的顶级类

    我个人理解该类的主要作用就是为了复用,比如Activity,Dialog中都使用了它,上面也讲到过我们自己来显示一个特殊的window的时候需要调用windowManager.addView方法,加入没有PhoneWindow,那我们自己在Activity,Dialog中就需要写一大堆的重复添加view的方法,并且还得处理各种事件,那岂不是很麻烦,因此PhoneWindow的诞生了,同时它也屏蔽了一些复杂的细节,让使用者使用起来很方便,我们完全不需要关心window,windowManager这些东西,在activity 中只需要在onCreate方法中setContentView即可

    总结
    Window封装了整个界面的background及各种事件的处理机制的功能,但它不会参与绘制流程,真正的绘制还是view

    PhoneWIndow是WIndow的一个子类,不可以实例话该类,来添加一个特殊的window,它有一个很重要的内部类DecorView,该类是整个view tree的顶级view类,Activity,Dialog等都会持有该类的一个对象

    WindowManagerImpl是上层使用者添加一个特殊的window的,根据LayoutParams的不同来显示不同的window,其实最终是调用WindowManagerGlobal来进行添加的

    Activity的PhoneWindow添加过程

    Activity在初始化的时候会生成PhoneWIndow同时PhoneWindow的DecorView也会生成以及它的WindowManager。
    当Activity处于resume状态时,ActivityThread会查看view有没有添加入WindowManager中,没有则会调用windowManager.addView方法把DecorView加入WIndowManagerGlobal中,并且生成一个ViewRootImpl,调用ViewRootImpl的setView方法,整个view tree开始进行绘制

    在Activity处于destory状态时,ActivityThread会调用WindowManagerGlobal的removeView把DecorView移除

    相关文章

      网友评论

          本文标题:Android 窗口机制

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