学习一下android 16ms问题记录一下
手机屏幕是由许多的像素点组成的,每个像素点通过显示不同的颜色最终屏幕呈现各种各样的图像.
在GPU中有一块缓冲区叫做 Frame Buffer ,这个帧缓冲区可以认为是存储像素值的二位数组,
数组中的每一个值就对应了手机屏幕的像素点需要显示的颜色.
由于这个帧缓冲区的数值是在不断变化的,所以只要完成对屏幕的刷新就可以显示不同的图像了.
至于刷新工作手记的逻辑电路会定期的刷新 Frame Buffer的 目前主流的刷新频率为60次/秒 折算出来就是16ms刷新一次.
GPU 除了帧缓冲区 用以交给手机屏幕进行绘制外. 还有一个缓冲区 Back Buffer 这个用以交给应用的,让你往里面填充数据.
GPU会定期交换 Back Buffer 和 Frame Buffer 也就是让Back Buffer中的数据转到 Frame Buffer 然后交给屏幕进行显示绘制,
同时让原先的Frame Buffer 变成 Back Buffer 让程序处理.
这就与屏幕硬件电路的刷新频率保持了同步,如图所示
这也就是贯穿整个安卓系统的双缓冲机制,实际上的帧就保存在这两个缓冲区,A缓冲区用来显示当前帧,B缓冲区就用来缓存或者成为处理下一帧数据,这样就可以做到一边处理一边显示
Frame Buffer和Back Buffer的数据是自动完成交换的,我们需要处理的是根据需求向 Back Buffer中填充数据即可,
那么在向Back Buffer中国年填充数据期间此时如果需要两者交换处理怎么办呢.
由于在填充Back Buffer数据时 系统会将 Back Buffer 锁上,因此此时这次数据交换就会被放弃,
这样手机还是显示原来的内容等到下次完成交换再显示新的图像时一共需要的时间是32ms,这就是丢帧.
上面提到的双缓冲技术就是GPU加快栅格化的速度, 栅格化就是将向量图转化为机器可以识别的位图的一个过程,
这个过程是比较耗时复杂的,所以用到了双缓冲技术.
我们的ui组件呢? CPU会将ui组件计算成多边形(polygons)和纹理(textures),然后交给GPU进行栅格化渲染,
最后GPU将数据传给屏幕进行绘制显示.当然在CPU和GPU之间还需要经过OpenGL ES的处理,这个我也只是听过而已.
为了避免帧丢失,我们就要确保更新时间不要超过16ms
在向Back Buffer填充数据时 Back Buffer 会被锁定后,会将一个指向它的 Canvas 对象交给程序.
应用程序收到这个对象后按照视图层次从上往下遍历. 在view 的onDraw(Canvas canvas)方法中就是这个对象,
减少视图层可以减少canvas的传递时间
invalidate 方法会使视图重绘,所以减少该方法的使用同时合理的使用该方法也会降低丢帧率.
我们还需要知道,整个16ms并不是完全让我绘制界面的,还有layout,measue等方法的调用呢,所以留给用于绘制自己的界面的时间肯定是少于16ms的