【Android】用HandlerThread模擬AsyncTask功能(ThreadTask)


 

前言

AsyncTask是個好東西,能處理絕大多數應用線程和更新UI的任務,由於其內部使用了靜態線程池,如果你有一堆異步任務(例如全局定時更新數據、同一個Activity中多個AsyncTask同時執行)其中有不能馬上執行完的情況(例如網絡請求超時),那就糟了,其他任務都還等着呢,就會出現任務卡住的情況。此時就需要直接上Thread了,這里參考AsyncTask的API封裝了一個ThreadTask,便於必要時代碼替換,歡迎交流!

 

聲明

歡迎轉載,但請保留文章原始出處:)
博客園:http://www.cnblogs.com
農民伯伯: http://over140.cnblogs.com

 

 

正文

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;

public  abstract  class ThreadTask<Params, Progress, Result> {

     private HandlerThread mHandlerThread;
     private TaskHandler mHandler;
     private TaskHandler mUiHandler;
     private Params[] mParams;

     public ThreadTask() {
        mHandlerThread =  new HandlerThread("ThreadTask", android.os.Process.THREAD_PRIORITY_BACKGROUND);
        mHandlerThread.start();
        mHandler =  new TaskHandler(mHandlerThread.getLooper());
        mUiHandler =  new TaskHandler(Looper.getMainLooper());
    }

     protected  abstract Result doInBackground(Params... params);

     protected  void onPreExecute() {
    }

     protected  void onProgressUpdate(Progress... values) {
    }

     protected  final  void publishProgress(Progress... values) {
        mUiHandler.obtainMessage(MESSAGE_PROGRESS, values).sendToTarget();
    }

     protected  void onPostExecute(Result result) {
    }

     public  final  boolean isCancelled() {
         return mHandlerThread.isInterrupted();
    }

     public  final  void cancel( boolean mayInterruptIfRunning) {
         if (!mHandlerThread.isInterrupted()) {
             try {
                mHandlerThread.quit();
                mHandlerThread.interrupt();
            }  catch (SecurityException e) {
                e.printStackTrace();
            }  catch (Exception e) {
                e.printStackTrace();
            }
        }
        onCancelled();
    }

     protected  void onCancelled() {
    }

     public  void execute(Params... params) {
        mParams = params;
        onPreExecute();
        mHandler.sendEmptyMessage(MESSAGE_INBACKGROUND);
    }

     private  static  final  int MESSAGE_INBACKGROUND = 0;
     private  static  final  int MESSAGE_POSTEXECUTE = 1;
     private  static  final  int MESSAGE_PROGRESS = 2;

     private  class TaskHandler  extends Handler {

         public TaskHandler(Looper looper) {
             super(looper);
        }

        @SuppressWarnings("unchecked")
        @Override
         public  void handleMessage(Message msg) {
             switch (msg.what) {
             case MESSAGE_INBACKGROUND:
                mUiHandler.obtainMessage(MESSAGE_POSTEXECUTE, doInBackground(mParams)).sendToTarget();
                 break;
             case MESSAGE_POSTEXECUTE:
                onPostExecute((Result) msg.obj);
                mHandlerThread.quit();
                 break;
             case MESSAGE_PROGRESS:
                onProgressUpdate((Progress[]) msg.obj);
                 break;
            }
        }
    }
}

代碼說明:

由於onPreExecute和onPostExecute都在在主線程執行,又要保證執行的順序,所以采用Handler來控制執行順序,根據Loop的不同,Handler能切換在子線程中執行代碼還是在主線程中執行代碼。

 

文章

  Android AsyncTask完全解析,帶你從源碼的角度徹底理解

 

后期維護

2014-08-05  正常流程走完以后忘了調用HandlerThread的quit,代碼已經更新。

 

結束

除了不受線程池控制以外,還能被真正的cancel掉(AsyncTask是不能的,只是一個標記),寫的有些倉促,難免bug,歡迎反饋!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM