写了一个单线程的和多线程读写分开的图片切换,多线程同步用信号量实现:
二话不说,上图:
1.信号量基类:
package com.huangcheng.sem;
public abstract class Semaphore {
private int value = 0;
public Semaphore() {
}
public Semaphore(int initial) {
if (initial >= 0)
value = initial;
else
throw new IllegalArgumentException("initial < 0");
}
public final synchronized void P() throws InterruptedException {
while (value == 0)
wait();
value--;
}
protected final synchronized void Vc() {
value++;
notifyAll();
}
protected final synchronized void Vb() {
value++;
notifyAll();
if (value > 1)
value = 1;
}
public abstract void V();
public String toString() {
return ".value=" + value;
}
}
二元信号量继承类:
package com.huangcheng.sem;
public final class BinarySemaphore extends Semaphore {
public BinarySemaphore() {
super();
}
public BinarySemaphore(int initial) {
super(initial);
if (initial > 1)
throw new IllegalArgumentException("initial > 1");
}
public final synchronized void V() {
super.Vb();
}
}
3.Activity布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/background_btn">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="单线程"
android:textSize="20dip"
android:id="@+id/draw1_btn"
android:layout_marginLeft="30dip"/>
<Button
android:id="@+id/draw2_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="多线程"
android:textSize="20dip"
android:layout_toRightOf="@id/draw1_btn"/>
<Button
android:id="@+id/quit_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="退出程序"
android:textSize="20dip"
android:layout_toRightOf="@id/draw2_btn"/>
</RelativeLayout>
<SurfaceView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/surfaceview_draw"/>
</LinearLayout>
4.Activity类:
package com.huangcheng.draw;
import java.lang.reflect.Field;
import java.util.ArrayList;
import com.huangcheng.sem.BinarySemaphore;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class SurfaceViewDraw2Activity extends Activity {
/** Called when the activity is first created. */
private Button draw1_btn, draw2_btn,quit_btn;
private SurfaceView surfaceview_draw;
private SurfaceHolder surfaceholder;
private Thread draw1_thread, prepare2_thread, draw2_thread;
private BinarySemaphore bsem1,bsem2;
ArrayList<Integer> imgList = new ArrayList<Integer>();
int imgWidth, imgHeight;
Bitmap bitmap;// 独立线程读取,独立线程绘图
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
draw1_btn = (Button) findViewById(R.id.draw1_btn);
draw2_btn = (Button) findViewById(R.id.draw2_btn);
quit_btn=(Button)findViewById(R.id.quit_btn);
surfaceview_draw = (SurfaceView) findViewById(R.id.surfaceview_draw);
surfaceholder = surfaceview_draw.getHolder();
surfaceholder.addCallback(new DrawCallBack());
bsem1 = new BinarySemaphore(1);
bsem2 = new BinarySemaphore(0);
draw1_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
draw1_thread.start();
}
});
draw2_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
prepare2_thread.start();
draw2_thread.start();
}
});
quit_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
bitmap=null;//设置位图为null防止空指针报错
if(!draw1_thread.isInterrupted()){
draw1_thread.interrupt();
}
if(!prepare2_thread.isInterrupted()){
prepare2_thread.interrupt();
}
if(!draw2_thread.isInterrupted()){
draw2_thread.interrupt();
}
SurfaceViewDraw2Activity.this.finish();
}
});
draw1_thread = new Thread() {
int imgIndex = 0;
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while (!this.isInterrupted()) {
Canvas c = surfaceholder.lockCanvas(new Rect(0, 0,
0 + imgWidth, 0 + imgHeight));
Bitmap bmImg = BitmapFactory.decodeResource(getResources(),
imgList.get(imgIndex));
c.drawBitmap(bmImg, 0, 0, new Paint());
imgIndex++;
if (imgIndex == imgList.size())
imgIndex = 0;
surfaceholder.unlockCanvasAndPost(c);// 更新屏幕显示内容
ClearDraw(0, 0, imgWidth, imgHeight);
}
}
};
prepare2_thread = new Thread() {
int imgIndex = 0;
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while (!this.isInterrupted()) {
try {
bsem1.P();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bitmap = BitmapFactory.decodeResource(getResources(),
imgList.get(imgIndex));
imgIndex++;
System.out.println("imgIndex:"+imgIndex);
if (imgIndex == imgList.size())
imgIndex = 0;
bsem2.V();
}
}
};
draw2_thread = new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while (!this.isInterrupted()) {
try {
bsem2.P();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Canvas c = surfaceholder.lockCanvas(new Rect(0, imgHeight,
0 + imgWidth, 0 + imgHeight));
if(bitmap!=null){
c.drawBitmap(bitmap, 0, imgHeight, new Paint());
}
System.out.println("bitmap:");
surfaceholder.unlockCanvasAndPost(c);
ClearDraw(0, imgHeight, imgWidth, imgHeight);
bsem1.V();
}
}
};
}
class DrawCallBack implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
Log.i("Surface:","Change");
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
Log.i("Surface:", "Create");
// 用反射机制来获取资源中的图片 ID 和尺寸
Field[] fields = R.drawable.class.getDeclaredFields();
for (Field field : fields) {
if (!"ic_laucher".equals(field.getName())) {
int index = 0;
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();
}
// 保存图片 ID
imgList.add(index);
}
}
Bitmap bmImg = BitmapFactory.decodeResource(getResources(),
imgList.get(0));
imgWidth = bmImg.getWidth();
imgHeight = bmImg.getHeight();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
Log.i("Surface:","Destory");
}
}
// 消除画得图
private synchronized void ClearDraw(int x1,int y1,int x2,int y2) {
Canvas canvas = surfaceholder.lockCanvas(new Rect(x1, y1, x2, y2));
canvas.drawColor(Color.BLACK);// 清除画布
surfaceholder.unlockCanvasAndPost(canvas);
}
}
欢迎大家拍砖~~~~~~~~~~