美文网首页
Android窗口管理(2)——消息传递

Android窗口管理(2)——消息传递

作者: 李牙刷儿 | 来源:发表于2017-04-23 12:09 被阅读146次

    本文内容参考:Android 核心分析(13) -----Android GWES之Android窗口管理
    上一篇文章主要讲述了窗口的基本结构,那么在这样的结构下,系统如何管理窗口,如何下发事件,如何获取窗口状态?这篇博客将对这部分的内容进行介绍。
    Android在窗口管理上采用了最为经典的C/S模式,Client端是各个Activity中的window,而Service端就是系统持有的窗口管理器Window Manager。

    总体结构

    Window是顶级的窗口概念,而Activity中的DecorView则是窗口中的顶级View,创建Activity时,DecorView会attach到Activity的窗口中,同时也被加入到WindowManager中,WindowManager使用WindowState与该View相对应。


    两者之间通过建立session会话进行通信,而这里的session采用的还是Android中最重要的IPC方式——AIDL。Activity在建立窗口后需要将该窗口注册到WindowManager中,这个过程涉及到在Activity本地创建一个WindowManager的代理,Activity通过这个代理和远程WindowManager进行会话,会话的通道是IWindowSession,本质上就是一个AIDL通信过程。 这里写图片描述
    会话是双向的,为了将消息发送给对应的Window,WindowManager通过IWindow接口将对应的消息发送给Window端对应的处理函数。

    Client端——Activity

    首先来看一下Client端,通过我的上一篇博客Android窗口管理(1)——窗口基本架构我们知道了Activity端的窗口结构,并且知道了Window,PhoneWindow都不是很重要的概念,实际真正干事的还是ViewRoot


    Activity在创建的时候会调用onAttach()创建PhoneWindow这个类,并在handleResumeActivity时将窗口加入到WindowManager中,不过加入的实际上并不是窗口,而是DecorView。所以其实在客户端的核心概念只有ViewRootDecorView以及ViewGroup。其中后面两者主要还是View的概念,真正完成与WindowManager进行通信的还是ViewRoot这个家伙。

    ViewRoot

    ViewRoot的真正实现类是ViewRootImplViewRoot通过与WindowManager进行通信完成addView以及消息下发。


    ViewRoot通过IWindowSession将窗口加入到WindowManager中。
    这里写图片描述
    WindowManager通过IWindow接口下发事件到Activity
    所以ViewRoot其实本质上是一个Handler,用于接收消息并处理消息。
    Activity利用getSystemService来获取WindowManagerImpl实例,而这个实例实际上就是WindowManager在客户端本地的代理:
    wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE);
    

    之后再调用addView接口通过WindowManagerImpl将窗口添加到WindowManager中。在addView的过程中,WindowManagerImpl会建立起View,Layout,ViewRoot之间的对应关系,然后利用IWindowSession传递给WindowManager

    Server端——WindowManager

    WindowManager是服务端管理窗口的组件,它管理的是各个应用的顶级窗口,也即DecorView。将所有的窗口归置到一个统一的系统服务WindowManagerService管理是Android系统的设计思想,这样的机制并不难理解,系统总要有一个总管各个窗口的管家嘛,总不能任其自生自灭。WindowManagerService的主要工作包括:
    Window Service大体上实现了如下的功能:,

    (1)Z-ordered的维护函数
    (2)输入法管理
    (3)AddWindow/RemoveWindow
    (4)Layerout
    (5)Token管理,AppToken
    (6)活动窗口管理(FocusWindow)
    (7)活动应用管理(FocusAPP)
    (8)转场动画
    (9)系统消息收集线程
    (10)系统消息分发线程

    在服务端窗口对象叫作WindowState,Server端维护一个mWindow,其实就是一个按Z-order排序的窗口数组。mWindowMap用于记录<Client:Binder,WindowState对象>
    WindowState通过本地的client实例维护IWindow实例,同时利用该实例访问窗口。

    FocusWindow活动窗口如何计算

    原理其实很简单,首先找到前台应用,然后根据mWindow找到Z-order顺序中第一位次的窗口,该窗口就是活动窗口。

    为什么要提出Token这个概念

    Token在本质上就是一个标示符,应用程序使用改标示符来找到该应用的窗口。AppToken:<Token:IBinder,allWindows>。通过Token就可以管理该应用的所有窗口。

    WindowManager消息与分发

    下面再来说一下WindowManager的系统消息收集与分发过程。WindowManagerService在内部维护了一个KeyQ的消息队列,同时还有两个线程:

    1.InputDeviceReader
    2.InputDispatcherThread

    InputDeviceReader使用Native函数readEvent从driver中读取RawEvent并放到KeyQ队列中。
    InputDispatherThread负责从KeyQ队列中读取事件,并在WindowManager找到对应的窗口,利用该窗口的IWindow接口下发事件。

    相关文章

      网友评论

          本文标题:Android窗口管理(2)——消息传递

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