On Android, and in general, you want your application or game to be responsive. So operations that take a long time to finish or block I/O should not be preformed on the UI thread otherwise the UI becomes clunky and unresponsive. To solve this problem any CPU intensive or I/O blocking operation are preformed in a separate thread. Unfortunately this creates another problem, which is how do we update and control the UI from this separate worker thread.

This is where Handlers come into play they allow you to send Messages (information and instructions) from the worker thread to the UI thread. A Message can contain ints using the fields arg1 and arg2 and an arbitrary Object using the obj or a Bundle using the setData(Bundle data) method.

So here’s an example of how to use Handlers:

public class DataView extends View {
	final static int FAILURE = 123, DATA = 124;
	DataHandler handler;
	ArrayList data;
	boolean failure = false;

	public DataView(Context context, AttributeSet attrs) {
		super(context, attrs);
		handler = new DataHandler();
		(new Thread(new WorkerRunnable(this))).start();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// draw something based on data…
	}	

	private class DataHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case FAILURE:
				failure = true;
				invalidate();
				break;
			case DATA:
				data = (ArrayList) msg.obj;
				invalidate();
				break;
			default:
				super.handleMessage(msg);
				break;
			}
		}
	}

	@Override
	public Handler getHandler() {
		return handler;
	}

}
public class WorkerRunnable implements Runnable {

	private DataView dataView;
	private ArrayList dataObjects = new ArrayList(10);

	public WorkerRunnable(DataView dataView) {
		this.dataView = dataView;
	}

	@Override
	public void run() {
		boolean success = true;

		// some io or cpu heavy operations

		Message msg = Message.obtain();
		if(success){
			msg.what = DataView.DATA;
			msg.obj = dataObjects;
		}else{
			msg.what = DataView.FAILURE;
		}
		dataView.getHandler().sendMessage(msg);
	}
}

Explanation

The DataView spawns a Thread that runs a WorkRunnables code, which performs some IO or CPU heavy operations. The WorkRunnable informs the UI once it has finished (or failed) by sending messages to the custom written Handler.

Leave a Reply