Android 绘图时实现双缓冲
一、双缓冲技术原理:
在内存中创建一片内存区域,把将要绘制的图片预先绘制到内存中,在绘制显示的时候直接获取缓冲区的图片进行绘制。更具体一点来说:先通过setBitmap方法将要绘制的所有的图形绘制到一个Bitmap上也就是先在内存空间完成,然后再来调用drawBitmap方法绘制出这个Bitmap,显示在屏幕上。
二、双缓冲技术出现的缘由
当一个动画争先显示时,程序又在改变它,前面的画面还没显示完,程序又要求重新绘制,这样屏幕就会不停闪烁。为了避免闪烁,使绘制的内容有一个平滑的过度,所以就出现了双缓冲技术——》将要处理的图片都放在内存中处理好后,再将其一次性显示到屏幕上。这样出来的就是完整的图像,不会出现闪烁现象。
二、双缓冲技术的优缺点
优点:
1.绘制过程中一般不会出现闪烁现象,能使动画平滑过度。
2.高效,将图像一次性绘制到屏幕上比一次一次的绘制要高效的多。
缺点:
当图片过大时会严重的消耗内存
三、实现双缓冲的步骤
1.创建一片内存区域用于存放目标Bitmap
// 创建一个200*200的缓冲区 bitmapBuffer = Bitmap.createBitmap(200, 200, Config.ARGB_8888);
2.设置目标内容绘制到缓冲区
// 设置将目标内容绘制在“缓冲区” canvas.setBitmap(bitmapBuffer);
3.把将要绘制的图片绘制到缓冲区
// 把将要绘制的图片绘制到缓冲区 canvas.drawBitmap(bitmap, 0, 0, paint);
4.在onDraw方法中将缓冲区中的内容绘制到屏幕上
//将缓冲区的图片绘制到屏幕上 canvas.drawBitmap(bitmapBuffer, 0,0, paint);
四、双缓冲技术的实现代码:备注一下,其实SurfaceView和GLSurfaceView已经实现了双缓冲技术,建议在做动画和游戏时使用这两个view
1.DoubleBufferingView.java
package cn.yw.lib.doublebuffering; import cn.yw.lib.R; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.util.Log; import android.view.View; /** * 双缓冲View * * @author yw-tony * */ public class DoubleBufferingView extends View implements Runnable { private Bitmap bitmap = null; private Paint paint = null; // 创建一个Bitmap缓冲区 private Bitmap bitmapBuffer; private Canvas canvas; public boolean flag = true;// 线程结束标记,默认线程是开启的 public DoubleBufferingView(Context context) { super(context); initBuffering(context); // 开启线程进行图片绘制 new Thread(this).start(); } /** * 初始化缓冲区 */ private void initBuffering(Context context) { // 装载资源 bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher); // 创建一个200*200的缓冲区 bitmapBuffer = Bitmap.createBitmap(200, 200, Config.ARGB_8888); canvas = new Canvas(); // 设置将目标内容绘制在“缓冲区” canvas.setBitmap(bitmapBuffer); // 实例化一个画笔 paint = new Paint(); // 把将要绘制的图片绘制到缓冲区 canvas.drawBitmap(bitmap, 0, 0, paint); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 将缓冲区的图片绘制到屏幕上 canvas.drawBitmap(bitmapBuffer, 0, 0, paint); Log.e("draw", "正在努力绘制!"); } @Override public void run() { while (flag) { try { postInvalidate();// 更新View界面 Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } } }
2.DoubleBufferingActivity.java
package cn.yw.lib.doublebuffering; import android.app.Activity; import android.os.Bundle; /** * 测试双缓冲 * * @author yw-tony * */ public class DoubleBufferingActivity extends Activity { private DoubleBufferingView bufferView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); bufferView = new DoubleBufferingView(this); setContentView(bufferView); } // 当用户按下回退键时结束线程 @Override public void onBackPressed() { super.onBackPressed(); bufferView.flag = false; } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。