留着学习,后续了解屏幕闪烁成因以及解决方法 。
所谓双缓冲就是两个线程同时进行某一项工作, 游戏中使用双缓冲主要是为了解决画图闪烁的问题和提高画图的效率。当使用SurfaceView画图的时候,会锁定画图的区域,也就是说这块区域只有本次画图结束之后才能进行下次画图,而我们在画图的时候往往需要进行一些预处理的工作之后才能绘制,比如先要读取图片,而这样是比较耗时的。如果我们使用一个线程专门来进行预处理的工作,一个线程专门用来画图,这样就可以有效的提高画图的效率。下面和大家分享一下代码:
程序运行结果就是几张图片在循环快速的绘制。
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>