zoukankan      html  css  js  c++  java
  • 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;
        }
    }

      

  • 相关阅读:
    sql server 如何查看这个数据库有多少张表并具体显示出来
    SQL Server2008 SP1安装 查找安装媒体怎么解决
    检测到在集成的托管管道模式下不适用的 ASP.NET 设置。
    sql不记得用户名跟密码怎么办
    必背系列之数据库常用语法
    select * from 多张表的用法
    SAP与Oracle ERP
    with as的用法
    IIS启动网站--HTTP错误500.21
    SqlServer2012--备份介质集不完整 ,介质集有2个介质簇但只提供了1个
  • 原文地址:https://www.cnblogs.com/tony-yang-flutter/p/3522861.html
Copyright © 2011-2022 走看看