Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行,常用的方法是利用Handler来实现UI线程的更新的,其本质就是利用ui主线程发送消息由另外一个非ui线程进行具体的绘制工作。
使用方法非常简单,下面的例子就是利用一个Handler的handleMessage复写方法收取Message对象发送的消息进行绘制一个运行于蓝色直线上的滚动的圆形。
package com.test.surfaceview;
import java.lang.reflect.Field;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
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.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
public class TestsurfaceviewActivity extends Activity {
private final static String TAG = "TestsurfaceviewActivity";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
onHanlderTest();
}
private final static int MSG_UPDATE_START = 1;
private final static int MSG_UPDATE_STOP = 2;
private final static int MSG_UPDATE_REGION = 3;
private DrawViewer dv = null;
private void onHanlderTest(){
dv = new DrawViewer(this);
new Thread(new myTestThread()).start();
this.setContentView(dv); //请务必注意这句,否则其内容将不是画在此DrawViewer上面
}
private class DrawViewer extends View {
private int center = 0;
public DrawViewer(Context ctx) {
super(ctx);
this.center = 30;
}
@Override
protected void onDraw(Canvas canvas){
Log.i(TAG,"onDraw curr position = "+ center);
center+= 10;
if(center >= 1280) center = 0;
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
mPaint.setAlpha(0x80);
canvas.drawCircle(center, 320, 40, mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawLine(0, 360, 1280, 360, mPaint);
}
}
Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
switch(msg.what){
case MSG_UPDATE_START:
Log.i(TAG,"revice MSG_UPDATE_START msg");
break;
case MSG_UPDATE_STOP:
Log.i(TAG,"revice MSG_UPDATE_STOP msg");
break;
case MSG_UPDATE_REGION:
Log.i(TAG,"revice MSG_UPDATE_REGION msg");
/**
* Invalidate the whole view. If the view is visible,
* onDraw(Canvas) will be called at some point in the future.
* This must be called from a UI thread. To call from a non-UI
* thread, call postInvalidate().
*/
dv.invalidate(); //实际调用的函数是DrawViewer中的onDraw()函数
break;
}
super.handleMessage(msg);
}
};
class myTestThread implements Runnable {
private void sendMsg(int what) {
Message message = new Message();
message.what = what;
myHandler.sendMessage(message);
}
public void run() {
this.sendMsg(MSG_UPDATE_START);
while (!Thread.currentThread().isInterrupted()) {
try {
this.sendMsg(MSG_UPDATE_REGION);
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
this.sendMsg(MSG_UPDATE_STOP);
}
}
}
用handler可以更好地使用我们在windows平台写代码的通过消息驱动的程序设计,比较容易理解,android还有其它的方法,后续!