SurfaceView與多線程
爲了實現數據加載和在SurfaceView上畫圖分離,採取線程分離,把數據加載放在一個線程中,把畫圖放在另外一個線程中。採用多線程的生產者和消費者模式,設置一箇中間類,即圖像處理類實現資源中的數據編碼成Bitmap類數據以及把Bitmap類數據畫在Surface上。同時採用模塊同步,實現線程的等待和喚醒。這樣畫圖的速度較使用標誌位,而不採取線程的等到與喚醒要快。
主程序:
package com.example.surfaceviewtest1;
import java.lang.reflect.Field;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Activity02 extends Activity {
private Button threadButton;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private ArrayList<Integer> imageList = new ArrayList<Integer>();
private ImageResource imageResource;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity02);
//獲得控件的引用
threadButton = (Button)findViewById(R.id.threadButton);
surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
//通過surfaceView對象獲得surfaceHolder對象
surfaceHolder = surfaceView.getHolder();
//給surfaceHolder添加回調函數
surfaceHolder.addCallback(new MyCallback());
threadButton.setOnClickListener(new ButtonListener());
}
class ButtonListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
imageResource = new ImageResource(Activity02.this, imageList, surfaceHolder);
new Thread(new LoadImage(imageResource)).start();
new Thread(new DrawImage(imageResource)).start();
}
}
/**
*MyCallback類用來實現對Surface狀態的變化的處理
* @author denglinyi
*
*/
class MyCallback implements SurfaceHolder.Callback{
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
int index = 0;
//利用反射機制獲取圖像的ID和大小
Field[] fields = R.drawable.class.getDeclaredFields();
for (Field field : fields) {
if (!"ic_action_search".equals(field.getName()) && !"ic_launcher".equals(field.getName())) {
try {
index = field.getInt(R.drawable.class);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
imageList.add(index);
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_activity02, menu);
return true;
}
}
圖像處理程序:
package com.example.surfaceviewtest1;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.SurfaceHolder;
public class ImageResource {
private Context context;
private Bitmap image;
private boolean flag=true;
private ArrayList<Integer> imageList;
private int size=0;
private int index=0;
private SurfaceHolder surfaceHolder;
public ImageResource(Context context, ArrayList<Integer> imageList,SurfaceHolder surfaceHolder) {
this.context = context;
this.imageList = imageList;
this.surfaceHolder = surfaceHolder;
size = imageList.size();
}
public void loadImage() {
synchronized (this) {
if (!flag) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (flag) {
image = BitmapFactory.decodeResource(context.getResources(), imageList.get(index));
System.out.println("loadImage--->" + System.currentTimeMillis());
System.out.println("index---->" + imageList.get(index));
index++;
if (index >= size) {
index = 0;
}
flag = false;
this.notify();
System.out.println("loadImage---->");
}
}
}
public void drawImage() {
synchronized (this) {
if (flag) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (!flag) {
Canvas canvas = surfaceHolder.lockCanvas(new Rect(0, 0, 500, 500));
canvas.drawBitmap(image, 0, 0, null);
surfaceHolder.unlockCanvasAndPost(canvas);
flag = false;
System.out.println("drawImage--->" + System.currentTimeMillis());
flag = true;
this.notify();
System.out.println("drawImage---->");
}
}
}
}
數據加載線程:
package com.example.surfaceviewtest1;
publicclass LoadImageimplements Runnable {
private ImageResourceimageResource;
public LoadImage(ImageResource imageResource) {
//TODO Auto-generated constructor stub
this.imageResource = imageResource;
}
@Override
publicvoid run() {
//TODO Auto-generated method stub
while (true) {
imageResource.loadImage();
}
}
}
畫圖線程:
package com.example.surfaceviewtest1;
publicclass DrawImageimplements Runnable {
private ImageResourceimageResource;
public DrawImage(ImageResource imageResource) {
//TODO Auto-generated constructor stub
this.imageResource = imageResource;
}
@Override
publicvoid run() {
//TODO Auto-generated method stub
while (true) {
imageResource.drawImage();
}
}
}