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还有其它的方法,后续!