这篇文章的内容, 原来是写在随笔10 里面的, 写着写着内容多了, 还是放到新的文章里面吧, 后面再添加其他的也方便.
前面我们已经知道了, View 的更新都是在 UI Main 线程中进行的, 有没有例外的呢? 答案是确定的!!!!
在官方文档中, "Dev Guide" -> 左边菜单点击 "Graphics", 在出来的文档中, 最后有一段话值得注意:
Note: On each pass you retrieve the Canvas from the SurfaceHolder, the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the entire surface. For example, you can clear the previous state of the Canvas by filling in a color with
or setting a background image with drawColor()
. Otherwise, you will see traces of the drawings you previously performed.drawBitmap()
1 2 3 4 => 更新的帧数
A B => 1,2帧 更新Canvas, 后面的帧不再画东西
A B => 保留的前一个Canvas状态
A B A B => 显示内容, 只考虑更新区域(局部或全屏).
如果有画东西C, 如果画的地方没有drawColor() 或 drawBitmap(), 那么画布状态为 canvasAC, 注意是重叠 , 而非覆盖, 所以在进行动画的区域, 请先清屏了再画, 不然将有前两帧的画面痕迹.
drawColor() 是全屏清屏, drawBitmap() 可以自己控制范围, 该方法的重载方法很多.
如果第三帧有画东西C, 并且这帧也画了东西D, 那画布状态为 canvasBD, 其前一个状态为 canvasAC.
在N-2>0的情况下, 第N 帧获取的画布竟然是 N-2 帧的画布, 而不是延续上一帧的画布, 并且画布被锁定了, 想换都不行.
本人菜鸟, 不是很理解android 这样做的用意. 让画面交替显示, 明显大部分情况下都不需要这样做吧, 就算需要交替画面, 我们也可以自己控制的. 并且第二帧过后, 我们每个SurfaceView 都将拥有2 个canvas 资源, 难道canvas 资源不值钱!!!!!
难道是 N-1 帧的canvas 在"页面显示后" 至 "新页面显示前" 这个过程中被系统或其他资源 "绑架" 了, 不给其他人动用, 本人无限 YY 中!!!!!
画 AB AC D E F G =>A画在不更新的区域, BCD...G 画在更新区域
显示 AB AC AD AE AF AG
局部更新 ->全屏更新->局部更新
画 B C D E AF AG H I J
显示 B C D E AF AG AH AI AJ =>设定A占有的区域比其他的多
画 A B C C D E F
显示 A B C C CD CE CF =>设定C占有的区域比其他的多.
ps. 获取全屏更新的画布---------->canvas = Holder.lockCanvas();
获取局部更新的画布----------->canvas = Holder.lockCanvas(new Rect(30,30,160,160)); //范围Rect对象自己定义.
Holder 为SurfaceView 的SurfaceHolder 对象变量.
双缓冲技术, 双即二! 一个缓冲是什么? 另一个缓冲又是什么? 本人一直的理解是, 一个缓冲是内存(甚至是CPU的缓存), 一个是显示设备.
画图的耗时和显示的耗时相比, 前者很多情况下明显要大于后者, 如果画图的操作过于复杂, 那这个差距就更大了. 一边画, 一边更新到屏幕上, 由于更新的频率快并且不均匀, 将造成一个后果--闪烁.
对于闪烁问题, 我们的前辈很聪明, 给出了一个双缓冲的方法. 很多情况下是, 我们先把显示内容画在内存中的一张位图上, 画好了, 再把这张位图拷贝到屏幕上. 这样做的好处是, 位图拷贝到屏幕上的耗时是比较稳定的, 在合理频率下, 画面的显示就会很稳定. 至于画图的操作有多复杂多困难, 跟画面显示没直接的关系了, 画面显示只能内存打交道, 画图也是在内存中暗地里进行着.
以上是个人的理解, 没有参考什么权威说法之类的东东, 反正我不认同那些说 SurfaceView 因为用了两个canvas, 所以是双缓冲的说法.
现在比较新的UI 框架, 有哪个的内置控件(组件)不是双缓冲的呢? 一般人能想到的, 那些大公司的高手没可能想不到, 控件都闪烁, 还不给人笑死.