应用层
Android显示过程的概括:Android应用程序把经过测量、布局、绘制后的surface缓存数据,通过SurfaceFlinger把数据渲染到显示屏幕上,通过Android的刷新机制来刷新数据。也就是说应用层负责绘制,系统层负责渲染,通过进程间通信把应用层需要绘制的数据传递到系统层服务,系统层服务通过刷新机制把数据更新到屏幕。
绘制原理中每个View绘制的三个步骤中Measure和Layout都是递归来获取View的大小和位置,层级越深,元素越多,耗时也就越长。
1.Measure
用深度优先规则递归得到所有试图(View)的宽、高;获取当前View的宽度childWidthMeasureSpec和高度childHeightMeasureSpec之后,
可以调用它的成员函数Measure来设置它的大小。如果当前正在测量的子视图child是一个视图容器,那么它又会重复执行操作,
直到它的所有子孙视图的大小都测量完成为止
2.Layout
用深度优先原则递归得到所有View的位置;当一个子View在应用程序窗口左上角的位置确定之后,再结合它在前边测量过程中确定的宽度和高度,就可以完全确定它在应用程序窗口中的布局。
3.Draw
目前Android有两种绘制方式,软件绘制CPU与硬件加速GPU,GPU的显示和绘制效率远高于CPU,但也有缺点:耗电,兼容问题,内存大(使用openGL的接口至少需要8MB内存)
系统层
真正把需要显示的数据渲染到屏幕上,通过SufaceFlinger服务实现的
简单过程
1.响应客户端事件,创建Layer与客户端的Surface建立连接
2.接受客户端数据与属性,修改Layer属性,比如尺寸、颜色、透明度等
3.将创建的Layer内容刷新到屏幕上
4.维持Layer序列,并对Layer最终输出做出裁剪计算
在Android的显示系统,使用了Android的匿名共享内存:SharedClient,每一个应用和SurfaceFlinger之间都会创建一个SharedClient,每个SharedClient中最多创建31哥SharedBufferStack,每个Surface都对应一个SharedBufferStack,也就是一个window。同时每个SharedBufferStack又包含了两个或三个缓冲区,surfaceFlinger在驱动层把缓冲区中的数据渲染到屏幕。
FPS
这个表示每秒传递的帧数,老生常谈16ms发一次VSYNC信号,触发UI渲染,这就是60FPS,超了就会丢帧感到卡顿不流畅,可能是Layout太复杂了,也可能是UI上有太多的绘制单元,还可能是动画执行的次数太多
卡顿的根本原因
主要就是两个方面
1.绘制任务太重,绘制一帧的内容耗时太长
2.主线程太忙,导致VSYNC信号来的时候还没准备好数据导致丢帧
主线程主要干的工作
1.UI生命周期控制
2.系统事件处理
3.消息处理
4.界面布局
5.界面绘制
6.界面刷新
除了这些之外,其他活尽量避免让主线程去干