1、双缓冲机制:
至于什么是双缓冲机制,我这里简单介绍一下,大家可以上网查看别人的资料都很详细了:这种机制的原理就是第一次显示缓存A的内容,下次显示缓存B的内容,在下次又显示缓存A的内容,即两个缓存中的内容交替显示,并且两个缓存中的数据是相互独立的。
这个机制在surfaceview中是如何实现的呢?通过这几个方法:surfaceholder.lockCanvas--surfaceholder.unlockCanvasAndPost方法实现的,即第一次这两个API是操作的缓存A,下次操作缓存B。
2、闪屏现象:
先来看看我的代码:
全局变量isFirstDraw = true;
try{
Canvas canvas = mHolder.lockCanvas();
if(isFirstDraw){
isFirstDraw = false;
canvas.drawColor(Color.WHITE);
}
canvas.drawCircle(100,100,50,null);
}catch(Exception e){
}finally{
mHolder.unlockCanvasAndPost(canvas);
}
上面的代码在异步线程中绘制时会出现闪屏现象,原因就是因为第一次绘制的时候是操作的缓存A,这次绘制是有绘制背景颜色的,但是下次绘制缓存B的时候是没有绘制背景的,所以在他们交替显示的时候就会出现背景快速变换而导致的闪屏现象。
再来看看正常的代码:
private Paint paint = new Paint();
Canvas canvas = null;try {
canvas = mHolder.lockCanvas();
if(bitmapCache == null){
bitmapCache = Bitmap.createBitmap(canvas.getWidth(),canvas.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas1 = new Canvas(bitmapCache);
canvas1.drawColor(Color.WHITE);
canvas1.drawCircle(100,100,50,null);
canvas.drawBitmap(bitmapCache,0,0,paint);
}else {
Canvas canvas1 = new Canvas(bitmapCache);
canvas1.drawCircle(100,100,50,null);
canvas.drawBitmap(bitmapCache,0,0,paint); }
} catch (Exception e) {
e.printStackTrace();
} finally {
if(mDrawing) mHolder.unlockCanvasAndPost(canvas);
}
上面代码的实现思路就是:不管当前操作的缓存是缓存A还是缓存B,我们在全局里面新建一个Bitmap对象作为副本,
不管当前操作的是哪个缓存,都是先在副本里面绘制好,最后在绘制到canvas = mHolder.lockCanvas()这个canvas上。
需要注意的是:在副本上绘制的时候是在上一次绘制的内容基础上接着绘制的,即保留了上一次的绘制的东西。
这样子做的好处就是可以保证当前缓存内容是在另外一个缓存内容的基础上修改的,这样就不会出现闪屏等两个缓存交替产生的不和谐现象。