前言
AsyncTask是個好東西,能處理絕大多數應用線程和更新UI的任務,由於其內部使用了靜態線程池,如果你有一堆非同步任務(例如全域定時更新資料、同一個Activity中多個AsyncTask同時執行)其中有不能馬上執行完的情況(例如網路請求逾時),那就糟了,其他任務都還等著呢,就會出現任務卡住的情況。此時就需要直接上Thread了,這裡參考AsyncTask的API封裝了一個ThreadTask,便於必要時代碼替換,歡迎交流!
歡迎轉載,但請保留文章原始出處:)
部落格園:http://www.cnblogs.com
農民伯伯: http://over140.cnblogs.com
本文
android.os.Handler;
android.os.HandlerThread;
android.os.Looper;
android.os.Message;
ThreadTask<Params, Progress, Result> {
HandlerThread mHandlerThread;
TaskHandler mHandler;
TaskHandler mUiHandler;
Params[] mParams;
ThreadTask() {
mHandlerThread = HandlerThread("ThreadTask");
mHandlerThread.start();
mHandler = TaskHandler(mHandlerThread.getLooper());
mUiHandler = TaskHandler(Looper.getMainLooper());
}
Result doInBackground(Params... params);
onPreExecute() {
}
onProgressUpdate(Progress... values) {
}
publishProgress(Progress... values) {
mUiHandler.obtainMessage(MESSAGE_PROGRESS, values).sendToTarget();
}
onPostExecute(Result result) {
}
isCancelled() {
mHandlerThread.isInterrupted();
}
cancel( mayInterruptIfRunning) {
(!mHandlerThread.isInterrupted()) {
{
mHandlerThread.quit();
mHandlerThread.interrupt();
} (SecurityException e) {
e.printStackTrace();
} (Exception e) {
e.printStackTrace();
}
}
onCancelled();
}
onCancelled() {
}
execute(Params... params) {
mParams = params;
onPreExecute();
mHandler.sendEmptyMessage(MESSAGE_INBACKGROUND);
}
MESSAGE_INBACKGROUND = 0;
MESSAGE_POSTEXECUTE = 1;
MESSAGE_PROGRESS = 2;
TaskHandler Handler {
TaskHandler(Looper looper) {
(looper);
}
@SuppressWarnings("unchecked")
@Override
handleMessage(Message msg) {
(msg.what) {
MESSAGE_INBACKGROUND:
mUiHandler.obtainMessage(MESSAGE_POSTEXECUTE, doInBackground(mParams)).sendToTarget();
;
MESSAGE_POSTEXECUTE:
onPostExecute((Result) msg.obj);
;
MESSAGE_PROGRESS:
onProgressUpdate((Progress) msg.obj);
;
}
}
}
} 代碼說明:
由於onPreExecute和onPostExecute都在在主線程執行,又要保證執行的順序,所以採用Handler來控制執行順序,根據Loop的不同,Handler能切換在子線程中執行代碼還是在主線程中執行代碼。
文章
結束
除了不受線程池控制以外,還能被真正的cancel掉(AsyncTask是不能的,只是一個標記),寫的有些倉促,難免bug,歡迎反饋!