概述

Android系统采用一种称为Surface的UI架构为应用程序提供用户界面。在Android应用程序中,每一个Activity组件都关联有一个或者若干个窗口,每一个窗口都对应有一个Surface。有了这个Surface之后,应用程序就可以在上面渲染窗口的UI。最终这些已经绘制好了的Surface都会被统一提交给Surface管理服务SurfaceFlinger进行合成,最后显示在屏幕上面。无论是应用程序,还是SurfaceFlinger,都可以利用GPU等硬件来进行UI渲染,以便获得更流畅的UI。在Android应用程序UI架构中,还有一个重要的服务WindowManagerService,它负责统一管理协调系统中的所有窗口,例如管理窗口的大小、位置、打开和关闭等。

这系列讲Android应用程序的Surface机制,阐述Activity、Window和View的关系,以及应用程序、WindowManagerService和SurfaceFlinger协作完成UI渲染的过程。

  • Android UI架构概述
  • Android应用程序UI框架
  • WindowManagerService
  • SurfaceFlinger
  • Android多屏支持
总体架构

窗口(Window)的结构
  • ViewRootImpl是一个虚拟根View,用来控制窗口的渲染,以及用来与WindowManagerService、SurfaceFlinger通信
  • DecorView是窗口的真正根View
  • ContentView描述窗口的主题风格

Window与Activity的关系

Activity所对应的Window实际上是一个PhoneWindow

Activity/Window的上下文

Window的虚拟根View -- ViewRootImpl

窗口绘图表面 -- Surface

窗口标志 -- W

窗口会话 -- Session

窗口视图 -- View

Android应用程序UI的绘制过程

软件渲染过程

硬件渲染过程

Display List是什么?
Display List是一个缓存绘制命令的Buffer
Display List的好处?
当View的某些属性发生改变时,只需要修改相应的Buffer中对应的属即可,例如Alpha属性,而无需对整个View进行重绘

Android应用程序UI的绘制时机 – Without Vsync -- Jank

Android应用程序UI的绘制时机 – With VSync

Android应用程序UI的绘制时机 – With Vsync and Double Buffering

Android应用程序UI的绘制时机 – With Vsync and Triple Buffering

Android系统的VSync实现
  • SurfaceFlinger内部维护有一个EventThread,用来监控显卡的VSync事件
  • Android应用程序通过注册一个DisplayEventReceiver来接收SurfaceFlinger的VSync事件
  • Android应用程序接收到重绘UI请求,通过前面注册的DisplayEventReceiver向SurfaceFlinger请求在下一个VSync事件到来时产生一个VSync通知
  • Android应用程序获得VSync通知的时候,才会真正执行重绘UI的请求
WindowManagerService

职责

  • 计算窗口大小
  • 计算窗口Z轴位置
  • 管理输入法窗口
  • 管理壁纸窗口
  • 执行窗口切换

屏幕的基本结构

计算窗口大小 – Content Region

计算窗口大小 – Visible Region

计算窗口Z轴位置 – Window Stack

**计算窗口Z轴位置 – 计算时机 **

计算窗口Z轴位置 – 计算公式

Z = Base Layer + WINDOW_LAYER_MULTIPLIER(5)
Base Layer = T * TYPE_LAYER_MULTIPLIER(10000) + TYPE_LAYER_OFFSET(1000)

计算窗口Z轴位置 – 窗口主类型

计算窗口Z轴位置 – 窗口子类型

管理输入法窗口

输入法窗口在Window Stack的位置

管理壁纸窗口

壁纸窗口在Window Stack的位置

执行窗口切换

执行窗口切换 – Starting Window

执行窗口切换 – 动画

SurfaceFlinger

职责

  • 分配图形缓冲区
  • 合成图形缓冲区
  • 管理VSync事件

渲染流程

分配图形缓冲区

合成图形缓冲区

HWComposer实例:高通MDP4.0

合成图形缓冲区 – 可见性计算

管理VSync事件

Android多屏支持

从4.2开始支持多屏幕

屏幕类型

  • Primary Display

    • 设备自带的屏幕
    • 由SurfaceFlinger管理
  • External Display

    • 通过HDMI连接
    • 由SurfaceFlinger监控和管理
  • Virtual Display

    • 通过Miracast连接(基于Wifi Direct技术)
    • 由DisplayManagerService监控和管理
  • App通过android.app.Presentation接口在指定的屏幕上创建窗口
    http://developer.android.com/reference/android/app/Presentation.html