在SurfaceView中使用双缓冲

    所谓双缓冲就是两个线程同时进行某一项工作, 游戏中使用双缓冲主要是为了解决画图闪烁的问题和提高画图的效率。当使用SurfaceView画图的时候,会锁定画图的区域,也就是说这块区域只有本次画图结束之后才能进行下次画图,而我们在画图的时候往往需要进行一些预处理的工作之后才能绘制,比如先要读取图片,而这样是比较耗时的。如果我们使用一个线程专门来进行预处理的工作,一个线程专门用来画图,这样就可以有效的提高画图的效率。下面和大家分享一下代码:

MainActivity .java代码

package com.zyb.buffer;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity{
 private SurfaceView surfaceView;
 //用来控制SurfaceView
 private SurfaceHolder holder;
 //资源文件下所有图片的id
 private List<Integer> imgIds=new ArrayList<Integer>();
 private Bitmap bitmap;
 //图片宽高
 private int imgW,imgH;
 //程序是否退出
 private boolean isExit=false;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        surfaceView=(SurfaceView)findViewById(R.id.surfaceView);
        holder=surfaceView.getHolder();
        getImgs();
        Button draw=(Button)findViewById(R.id.draw);
        draw.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View arg0) {
    new Thread(new ReadThread()).start();
    new Thread(new DrawThread()).start();
   }
  });
    }
    /**
     * 得到资源文件下的所有图片
     */
    public void getImgs(){
     Class cls=R.drawable.class;
     Field[] fields=cls.getDeclaredFields();
     for(Field f:fields){
      //过滤的默认的icon图标
      if(!f.getName().equals("icon")){
       try {
        //获取到图片的id
        int id=f.getInt(cls);
     imgIds.add(id);
    } catch (IllegalArgumentException e) {
     e.printStackTrace();
    } catch (IllegalAccessException e) {
     e.printStackTrace();
    }
      }
     }
    }
    /**
     * 读取图片的线程
     * @author Administrator
     *
     */
    private class ReadThread implements Runnable{
     int index=0;
  @Override
  public void run() {
   while(!isExit){
    bitmap=BitmapFactory.decodeResource(getResources(), imgIds.get(index));
    imgW=bitmap.getWidth();
    imgH=bitmap.getHeight();
    index++;
    //读取到最后一张,重新再读
    if(index==imgIds.size()){
     index=0;
    }
   }
  }
     
    }
    /**
     * 画图线程
     * @author Administrator
     *
     */
    private class DrawThread implements Runnable{

  @Override
  public void run() {
   while(!isExit){
    if(bitmap!=null){
     //锁定这边矩形区域
     Canvas canvas=holder.lockCanvas(new Rect(0, 0, imgW, imgH));
     if(canvas!=null){
      try {
       canvas.drawBitmap(bitmap, 0, 0, new Paint());
      } catch (Exception e) {
       e.printStackTrace();
      }finally{
       //提交编辑
       holder.unlockCanvasAndPost(canvas);
      }
     }
    }
   }
  }
     
    }
 @Override
 protected void onDestroy() {
  isExit=true;
  super.onDestroy();
 }
   
}

 

main.xml内容

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
 <Button
  android:id="@+id/draw" 
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="开始双缓冲绘图"
     />
 <SurfaceView
  android:id="@+id/surfaceView"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  />
</LinearLayout>

 

程序运行结果就是几张图片在循环快速的绘制。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值