andorid- 利用非ui线程绘图方法

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


你可能感兴趣的:(thread,android,UI,windows,String,Class)