/** * @file TaskManager.java * * @revision: none * * @version 0.0.01 * @author: Zenki (zhajun), zenki2001cn@163.com * @date: 2011-1-26 下午04:50:45 */ package com.easyview.ebook.reader.engine.core; import java.util.ArrayList; import com.easyview.ebook.reader.engine.core.IActionCall; import com.easyview.ebook.reader.engine.core.EngineCode.EngineMsgCode; import com.easyview.ebook.reader.engine.util.Logger; import android.os.AsyncTask; import android.os.Handler; import android.os.Message; public class TaskManager { static private final String TAG = "TaskManager"; private ArrayList<ActionTask> mTaskQueue = new ArrayList<ActionTask>(); Thread mThread = null; static private TaskManager mTaskManager = null; static private TaskHandler mHandler = null; static private EngineCode mEngineError = null; private boolean mServerQuit = false; private volatile boolean mServerRunning = false; private ActionTask mCurTask = null; private TaskManager() { } static protected TaskManager getInstance() { if (null == mTaskManager) { mTaskManager = new TaskManager(); } if (null == mHandler) { mHandler = new TaskHandler(mTaskManager); } if (null == mEngineError) { mEngineError = EngineCode.getInstance(); } if (mTaskManager != null) { mTaskManager.serverStart(); } return mTaskManager; } synchronized private boolean hasElement() { if (mTaskQueue != null) { return !mTaskQueue.isEmpty(); } return false; } synchronized void put(ActionTask task, boolean head) { if (mTaskQueue != null) { if (head) { mTaskQueue.add(0, task); } else { mTaskQueue.add(task); } } else { Logger.dLog(TAG, "Task queue = " + mTaskQueue); return; } waitforServer(); try { synchronized (mThread) { Logger.vLog(TAG, "Add a task and notify server, has task = " + mTaskManager.hasElement()); if (mThread != null) { mThread.notify(); } } } catch (Exception e) { Logger.eLog(TAG, "Add task error" + e); } } synchronized protected void put(ActionTask task) { if (mTaskQueue.size() > 5) { return; } put(task, false); } synchronized private ActionTask take() { if ((mTaskQueue != null) && (mTaskQueue.size() > 0)) { return mTaskQueue.remove(0); } return null; } private void executeTask() { if (mCurTask != null) { Logger.vLog(TAG, "ExecuteTask status = " + mCurTask.getStatus()); DecAdapter adapter = mCurTask.getDecAdapter(); if (adapter != null) { adapter.setStop(false); } mCurTask.execute(); } } private void cancelTask() { if (mCurTask != null) { Logger.vLog(TAG, "CancelTask status = " + mCurTask.getStatus()); DecAdapter adapter = mCurTask.getDecAdapter(); if (adapter != null) { adapter.cancelProcessing(); } mCurTask.cancel(true); } } private synchronized void serverStop() { if (mThread != null) { if (mCurTask != null) { if (mCurTask != null) { mCurTask.cancel(true); mCurTask = null; } } mServerQuit = true; if (mTaskQueue != null) { mTaskQueue.clear(); mTaskQueue = null; } try { synchronized (mThread) { mThread.notify(); } } catch (Exception e) { } try { mThread.join(100); } catch (InterruptedException e) { Logger.eLog(TAG, "TaskManager join error"); } mThread = null; } Logger.vLog(TAG, "TaskManager server stop"); } private void waitforTask(ActionTask task) { Logger.vLog(TAG, "Waitfor other Task begin .... " + mCurTask.getStatus()); while (!task.getStatus().equals(AsyncTask.Status.FINISHED)) { // Logger.vLog(TAG, "waitfor Task .... " + mCurTask.getStatus()); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); Logger.eLog(TAG, "WaitforTask error"); break; } } Logger.vLog(TAG, "Waitfor other Task end .... " + mCurTask.getStatus()); } private void waitforServer() { int loop = 0; while (!mServerRunning) { Logger.vLog(TAG, "Waitfor server boot ....."); try { if (loop > 10) { break; } Thread.sleep(100); loop++; } catch (Exception e) { Logger.eLog(TAG, "WaitforServer error"); } mEngineError .setLastCode(EngineMsgCode.ENGINE_ERROR_TASK_SERVER_NOT_RUNNING); } } private synchronized void serverStart() { if (mThread == null) { mThread = new Thread() { public void run() { while (!mServerQuit) { if (!mTaskManager.hasElement()) { synchronized (this) { try { mCurTask = null; mServerRunning = true; Logger.vLog(TAG, "TaskManager server is waitting!"); wait(); } catch (InterruptedException e) { mEngineError .setLastCode(EngineMsgCode.ENGINE_ERROR_TASK_SERVER_CRASH); } } } cancelTask(); Logger.eLog(TAG, "Enter task handler loop !!!!"); try { while (mTaskManager.hasElement()) { mCurTask = mTaskManager.take(); mHandler.sendEmptyMessage(TaskHandler.MESSAGE_EXECUTE); waitforTask(mCurTask); } Logger.eLog(TAG, "Exit task handler loop ...."); } catch (Exception e) { Logger.eLog(TAG, e.toString()); if (mEngineError != null) { mEngineError .setLastCode(EngineMsgCode.ENGINE_ERROR_TASK_SERVER_CRASH); } } } mServerRunning = false; } }; mServerQuit = false; mThread.setDaemon(true); mThread.start(); Logger.vLog(TAG, "TaskManager server start ..."); } else { Logger.vLog(TAG, "TaskManager server is running"); } } synchronized protected void clearTask() { if ((mTaskQueue != null) && (mTaskQueue.size() > 0)) { mTaskQueue.clear(); } } protected void free() { if (mTaskManager != null) { mTaskManager.serverStop(); mTaskManager = null; } if (mHandler != null) { mHandler = null; } if (mEngineError != null) { mEngineError.free(); mEngineError = null; } Logger.dLog(TAG, "call free(): mThread = " + mThread + " mTaskManager = " + mTaskManager + " mEngineError = " + mEngineError); } static private class TaskHandler extends Handler { private TaskManager mTaskManager = null; static private final int MESSAGE_EXECUTE = 0; public TaskHandler(TaskManager taskManager) { mTaskManager = taskManager; } @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_EXECUTE: mTaskManager.executeTask(); break; default: break; } super.handleMessage(msg); } } static protected class ActionTask extends AsyncTask<Object, Object, Boolean> { IActionCall mAction; IActionCall mPredo; IActionCall mTodo; DecAdapter mAdapter; protected void setDecAdapter(DecAdapter adapter) { mAdapter = adapter; } protected DecAdapter getDecAdapter() { return mAdapter; } protected ActionTask(IActionCall action, IActionCall predo, IActionCall todo) { mAction = action; mPredo = predo; mTodo = todo; } @Override protected void onPreExecute() { super.onPreExecute(); if (mPredo != null) { Logger.dLog(TAG, "Predo action called"); mPredo.action(); } } @Override protected Boolean doInBackground(Object... params) { boolean res = false; if (mAction != null) { Logger.dLog(TAG, "Doinbackground action called"); res = mAction.action(); } return res; } @Override protected void onPostExecute(Boolean result) { super.onPostExecute(result); if (mTodo != null) { Logger.dLog(TAG, "Todo action called"); mTodo.action(); } } @Override protected void onCancelled() { super.onCancelled(); Logger.dLog(TAG, "Task onCancelled"); } } }