/* http://google-ukdev.blogspot.com/2009/01/crimes-against-code-and-using-threads.html * Some modification made by barclay to be consistent with formatting. */ package net.redgeek.android.eventrend.util; import android.os.Handler; import android.os.Message; public class GUITaskQueue { private static final int HANDLE_EXCEPTION = 0x1337; private static final int HANDLE_AFTER_EXECUTE = 0x1338; private TaskQueue mTaskQ; private Handler mHandler; private static GUITaskQueue singleton; public static GUITaskQueue getInstance() { if (singleton == null) { singleton = new GUITaskQueue(); singleton.start(); } return singleton; } private GUITaskQueue() { mTaskQ = new TaskQueue(); mHandler = new MyHandler(); } public void start() { mTaskQ.start(); } public void stop() { mTaskQ.stop(); } public void addTask(GUITask task) { mTaskQ.addTask(new GUITaskAdapter(task)); } /** * Adds a task with an associated progress indicator. The indicator's * showProgressIndicator() get called immediately then the * hideProgressIndicator() gets called before the GUITask's handle_exception() * or after_execute() method gets called. */ public void addTask(ProgressIndicator progressIndicator, GUITask task) { if (progressIndicator == null) { addTask(task); } else { addTask(new GUITaskWithProgress(task, progressIndicator)); } } private static class GUITaskWithProgress implements GUITask { private GUITask mDelegate; private ProgressIndicator mProgressIndicator; GUITaskWithProgress(GUITask _delegate, ProgressIndicator _progressIndicator) { mDelegate = _delegate; mProgressIndicator = _progressIndicator; mProgressIndicator.showProgressIndicator(); } public void executeNonGuiTask() throws Exception { mDelegate.executeNonGuiTask(); } public void onFailure(Throwable t) { mProgressIndicator.hideProgressIndicator(); mDelegate.onFailure(t); } public void afterExecute() { mProgressIndicator.hideProgressIndicator(); mDelegate.afterExecute(); } }; private static class GUITaskWithSomething { GUITask mGuiTask; Throwable mSomething; GUITaskWithSomething(GUITask _guiTask, Throwable _something) { mGuiTask = _guiTask; mSomething = _something; } } private void postMessage(int what, Object thingToPost) { Message msg = new Message(); msg.obj = thingToPost; msg.what = what; mHandler.sendMessage(msg); } private void postException(GUITask task, Throwable t) { postMessage(HANDLE_EXCEPTION, new GUITaskWithSomething(task, t)); } private class MyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case HANDLE_EXCEPTION: GUITaskWithSomething thingie = (GUITaskWithSomething) msg.obj; thingie.mGuiTask.onFailure(thingie.mSomething); break; case HANDLE_AFTER_EXECUTE: GUITask task = (GUITask) msg.obj; try { task.afterExecute(); } catch (Throwable t) { // LogX.e(t); } break; } super.handleMessage(msg); } } private class GUITaskAdapter implements Runnable { private GUITask mTask; GUITaskAdapter(GUITask _task) { mTask = _task; } public void run() { try { mTask.executeNonGuiTask(); postMessage(HANDLE_AFTER_EXECUTE, mTask); } catch (Throwable t) { postException(mTask, t); } } } }