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;

    }

}

 

 

  

你可能感兴趣的:(android)