概述
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