Android的UI显示原理总结

作者: susion哒哒 | 来源:发表于2019-01-28 16:18 被阅读12次

    本文是Android视图层源码分析系列第4篇文章,主要是对前几篇文章做一个总结,理解Android视图的主要组成部分和相互之间的工作逻辑。本文内容是基于Google Android Repo中的较新的源码分析而得来的。

    先来看一张Android视图层工作原理图,本文的内容就是逐一解释下图中各个模块的作用:

    Android视图层主要工作原理图.png

    Window相关

    Window可以说是Android Framework层提供的一个最基础的UI组件管理类,PhoneWindow是它的唯一实现类。它屏蔽了开发者与WindowManagerService的交互,统一了UI设计,并统一接收用户交互事件,比如背景、title和按键事件等。

    Activity/Dialog/Toast的UI展现都是依赖于Window来完成。对于UI编写,开发者只需要使用View相关即可。View最终会以ContentView的形式设置给Window:

    PhoneWindow.java

      public void setContentView(int layoutResID) {
      }
    

    DecorViewPhoneWindow根ViewGroupWindow提供了一些列的配置项,不同的配置项DecorView的UI组成会有一定的不同。关于Window的具体组成可以参考前面(深入剖析Window组成)[深入剖析Window组成.md]一文。

    WindowManager

    一个Window会有一个WindowManager。提到WindowManager就要提到WindowManagerGlobal。他们之间的区别是:

    • WindowManager : 它负责管理一个Window,并提供一系列对Window进行配置的flag。
    • WindowManagerGlobal : 它是一个单例类,负责管理应用所有的Window(其实并不是很严谨,应该是管理所有的ViewRootImpl)。并且它含有与WindowManagerService通信的Binder

    WindowManager所提供的API其实都是用来操作WindowManagerGlobal中的ViewRootImpl。比如WindowManager.addView(contentView)实际上是在WindowManagerGlobal中创建了一个与contentView对应的ViewRootImpl

    ViewRootImpl

    它负责管理一个具体的View Tree,比如DecorView及其所有子View。具体有下面这些职责:

    • 通过与WindowManagerService通信,创建Surface来显示其管理的View Tree
    • 管理整个View Tree的测量、布局、绘制。具体方法是performTraversals
    • 通过Choreographer来使整个ViewTree的UI刷新(测量、布局、绘制)与系统同步。

    Choreographer

    Choreographer用来控制同步处理输入(Input)、动画(Animation)、绘制(Draw)三个UI操作(UI显示的时候每一帧要完成的事情只有这三种)。其内部维护着一个Queue,使用者可以通过postXXX来把一些列待运行的UI操作放到Queue中。这些事件会在Choreographer接收显示系统的时间脉冲(垂直同步信号-VSync信号)后执行这些操作。比如ViewRootImpl对于View Tree的更新事件:

    ViewRootImpl.java

    void scheduleTraversals() {
        ...
         mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
    }
    

    Surface

    一个ViewRootImpl含有一个Surface(一个Surface含有一个Canvas)。可以把它理解为一个画布,通过Canvas可以在上面作画。ViewRootImpl的整个ViewTreedrawSurface上的。

    它实际上对应的是SurfaceFlinger中的Layer,在Surface上绘制的内容最终会由SurfaceFlinger来渲染。

    WindowManagerService

    它管理着所有应用程序的Window:

    • 管理所有Window的状态(WindowState)
    • SurfaceFlinger通信,完成Window的渲染

    通过ViewRootImpl可以向WindowManagerService添加一个Window:

    ViewRootImpl.java

    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
        ...
        //mWindow是一个`Binder`
        res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
        ...
    }
    

    mWindowSessionIWindowSession的实例,是一个与WindowManagerService通信的Binder。由WindowManagerGlobal创建和维护,一个应用程序只会有一个。

    WindowToken和WindowState

    WindowState用于在WindowManagerService中代表一个Window,它含有一个窗口的所有属性,它和ViewRootImpl是对应的。它被保存在WindowManagerServicemWindowMap集合中。mWindowMap是整个系统所有窗口的一个全集。

    WindowToken将属于同一个应用程序组件的窗口组织在一起。在WindowManagerService对窗口管理的过程中,用WindowToken代表一个应用组件。例如在进行窗口Z-Order排序时,属于同一个WindowToken的窗口(Window)会被安排在一起,也可以理解为渲染Window的Surface的Z轴顺序。一个token下可以有多个WindowState(Window):

    WindowManagerService.addWindow()

    win.mToken.addWindow(win);//一个token下会有多个win state
    

    SurfaceFlinger相关

    SurfaceFlinger是Android最重要的系统服务之一,它主要负责UI的渲染,具体可以说是Layer的合成和渲染。下面介绍的几个对象基本都是存在于WindowManagerService中的。是应用程序与SurfaceFlinger交互的关键对象。

    SurfaceControl

    可以简单的把它理解为Surface的管理者。它和Surface是一对一的关系。构建SurfaceControl的同时就会构造SurfaceViewRootImplSurface实际上和它指向的是同一个对象。它可以通过SurfaceComposerClient来与SurfaceFlinger通信。比如请求SurfaceFlinger创建Surface(Layer)

    SurfaceComposerClient

    这个对象也是进程唯一的,一个应用只有一个。可以通过它与SurfaceFlinger建立连接,从而与SurfaceFlinger通信。具体通信的功能是由Client对象来完成的。

    Client

    它是一个Binder,SurfaceComposerClient可以通过它来与SurfaceFlinger通信。比如通过它可以使SurfaceFlinger创建一个Layer。它也维护着一个应用程序所有的Layer

    Layer

    SurfaceFlinger管理着,分为多种不同的类型。它是一个可被SurfaceFlinger渲染的单元。它有一个BufferQueueProducer,里面维护着很多可以被渲染的GraphicBuffer,这个buffer可能被渲染完毕,也可能处于待渲染状态。

    想详细了解上面知识,阅读源码是权威的办法,也可以参考下面这些文章来理清思路:

    Android视图层源码分析

    理清Activity、View及Window之间关系

    Android Choreographer 源码分析

    一篇文章看明白 Android 图形系统 Surface 与 SurfaceFlinger 之间的关系

    老罗的Android之旅

    Android显示原理源码分析

    AndroidUI系列—浅谈图像渲染机制

    [深入理解Android]系列从书

    最后:

    欢迎关注我的Android进阶计划看更多干货

    欢迎关注我的微信公众号:susion随心

    微信公众号.jpeg

    相关文章

      网友评论

        本文标题:Android的UI显示原理总结

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