绘制原理简解

2016-7-28 chenhui Surface


一、

Surface 是 Android 用来实现显示界面的一套系统。

Android 应用程序在使用 Surface 时,总共会涉及到三个进程:应用程序自身、WindowManagerService(下简称WMS)和 SurfaceFlinger(下简称 SF)。

应用程序自身起到的作用是:提供一套界面的绘制方案。
WMS 起到的作用是:发送通知到应用程序,和处理应用程序的请求。
SF 起到的作用是:混合显示层,最终绘制到 FrameBuffer 上面。

其中应用程序本身和 SF 起到的作用是最大的,WMS 虽然必不可少,但相对来说对界面的绘制影响并不深,他更多起到的作用是为应用程序提供帮助,比如接收到一个输入消息时,把他传递给当前正在最前的 Activity 。

二、

我们都知道,界面的绘制从 Activity 的 onCreate() 开始,然后通常会调用 setContentView() 来设置一个最基本的布局。

通常来说,setContentView() 执行成功后,不做其他的任何事情,就能在屏幕上显示画面了。但是,我们通常会发现,除了我们要显示的内容外,他会额外多出来一些内容,比如界面顶部的标题栏。

那么这些标题栏是怎么来的?我们知道,ViewGroup 可以用来容纳其他的 View,所以说在我们调用 setContentView() 时,实际上是把 View 放到一个 ViewGroup 里。然而这个 ViewGroup 依然不是最底层的 ViewGroup,最底层的 ViewGroup 是一个继承自 FrameLayout 的 DecorView 对象,这个对象在创建时,会先加载诸如标题栏这些默认的 View,至于 setContentView(),都是在他的另一个子 ViewGroup 里实现的。

在 DecorView 之上,还有一个 Window 对象,这个 Window 对象用来管理当前窗口。

Activity 还有一个 WindowManager,他用来管理 Window,WindowManager 下面有一个 ViewRoot 对象,这个 ViewRoot 是 WindowManager 用来和 WMS 进行通信的;他有两条通信线路,一条发信息给 WMS,另一条则接收 WMS 发送过来的信息,比如键盘消息,WMS 就是发送给 ViewRoot,最后分发给 Activity。

三、

我们在编写 HTML 时,会经常遇到一个叫做 “ z-index ” 的属性。这个属性的作用是设置每一个元素的堆叠顺序。

在 Android 中,我们会发现他也有这种叠层效果。这个叠层效果是通过一个又一个显示层(Layer)来实现的。那么,这些显示层是什么?

我们知道,Android 是基于 Linux 实现的,而 Linux 中用来实现绘图的则是 FrameBuffer(简称FB),FrameBuffer 实质上是一块映射到用户空间的内存,当应用程序需要在显示屏上显示某些东西的时候,把图像的图像数据按照特定格式写到这块内存里即可。由于显示屏的驱动程序会定时从这块内存里读取图像数据,所以图像就显示在屏幕上了。

显示层保存的也是图像数据,但是这个图像数据并不会直接写到 FB 里,而是写到共享内存里,为什么是一块共享内存?正如上文所言,SF 起到的作用就是混合显示层以起到 “z-index 的效果,但显示层的数据是怎么来的?当然是应用程序写进去的,SF和应用程序是不同的进程,所以需要共享内存。也正是因为如此,显示层总共有两块共享内存,应用程序写其中一块,写完后 SF 从这块内存中读出数据;而 SF 正在读取数据时,另一块内存就空闲了,此时应用程序会开始把图像数据写到他上面,写完后 SF 继续读。这样子可以明显提高读写效率。


显示层对应一个 Surface 对象,一般来说,一个 Activity 只会有一个 Surface 对象,所以我们可以认为,Activity 一般情况下就是一个显示层。


四、

不管是什么控件还是方法,绘制最后都会落到 Canvas 这个对象上面,只不过大小的区别而已。那么 Canvas 是怎么创建的?

当然是根据绘制区域的 Left、Right、Top、Bottom 这四个参数来创建一个 Canvas 对象,并从显示层的空闲内存中取出开始地址,通过这个地址和 Canvas 对象,就可以把图像数据写到这块区域所在的内存里。

写完之后,就简单了,给 SF 发个消息,通知他可以刷新了。

SF 得到消息后,就会取出所有的显示层,根据堆叠顺序来混合这些显示层,最终写到 FB 里,屏幕上也就显示了图像。



发表评论:

Copyright ©2015-2016 freehui All rights reserved