異步的輕量級實現;
AsynceTask簡述:
1.功能類似於Handler,都是為了防止UI線程操作阻塞而衍生而來。
2.AsyncTask是Handler的一個輕量級實現,模型類似於IntentService於Service。都是為了更加方便操作。(因為一般的異步,我們都是開啟一個子線程或是匿名線程,缺點就是樣的實現對於線程的操作,控制是十分困難)
3.闡述下Handler,一般我們就認為Handler既一個Android消息處理器。默認情況下,他只接受當前線程的消息實例。
但是,當在一個多線程,比如子線程數據處理後更新Ui線程,此時只要存在Handler的指針,簡單的說就是實例對象時,消息的收發處理就能執行在不同的進程中了,這個也是我們常用到的異步處理手法。
4.從源代碼中看AsyncTask類中有 線程池,同樣也實例化了一個Handler對象。
說白了,AsyncTask只是對以上我們自己用handler,thread實現的異步做了一個很好的封裝,使用到線程池對於線程的銷毀和創建開銷大大減小
綜合了下:AsyncTask的異步處理相對於傳統的handler+Thread組合,減少程序中線程過多開銷過大。操作和管理更加方便。
AsyncTask的是實現:
和所有網上說的一樣,該對象必須在UiThread中實例化,然後執行execute方法。
copy下:AsyncTask定義了三種泛型類型 Params,Progress和Result。
•Params 啟動任務執行的輸入參數,比如HTTP請求的URL。
•Progress 後台任務執行的百分比。
•Result 後台執行任務最終返回的結果,比如String。
AsyncTask的執行分為四個步驟,每一步都對應一個回調方法,開發者需要實現一個或幾個方法。在任務的執行過程中,這些方法被自動調用。
onPreExecute(), 該方法將在執行實際的後台操作前被UI thread調用。可以在該方法中做一些准備工作,如在界面上顯示一個進度條。
doInBackground(Params...), 將在onPreExecute 方法執行後馬上執行,該方法運行在後台線程中。這裡將主要負責執行那些很耗時的後台計算工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。
onProgressUpdate(Progress...),在publishProgress方法被調用後,UI thread將調用這個方法從而在界面上展示任務的進展情況,例如通過一個進度條進行展示。
onPostExecute(Result), 在doInBackground 執行完成後,onPostExecute 方法將被UI thread調用,後台的計算結果將通過該方法傳遞到UI thread.
使用AsyncTask類,以下是幾條必須遵守的准則:
1) Task的實例必須在UI thread中創建
2) execute方法必須在UI thread中調用
3) 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法
4) 該task只能被執行一次,否則多次調用時將會出現異常
下面是我看了源代碼書寫下整個流程:
step 1:在UiThread中實例化類 執行了父類的構造 ( 代碼都簡寫了)
[java]
- public AsyncTask() {
-
- mWorker = new WorkerRunnable{//實現線程接扣的線程類。
- public Result call() {
- return doInBackground(mParams);//在類似於線程的run方法中調用doInBackground(mParams);
- }
- };
-
- mFuture = new FutureTask(mWorker) {//接受mWorker線程對象,實例化FutureTask類來操作線程。
- }
step 2 :在UiThread中調用AsyncTask對象的execute方法。
[java]
- public execute(){
-
- onPreExecute();//此方法中先調用了onPreExecute,也就是我們上文提到的准備工作。
-
- sExecutor.execute(mFuture);// 然後通過線程池操作構造中我們實例化的runnable對象。
-
- return this;
step 3 :根據step 2 可以知道 程序這步執行的應該是mFuture 代碼中的done()
[java]
- protected void done() {
- Message message;
- Result result = null;
- // 發送消息Tag和 消息處理結果。消息處理結果又用AsyncTaskResult類封裝起來,實例化對象傳遞進去的result就是上面doInBackground方法執行後的結果。
- message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
- new AsyncTaskResult<Result>(AsyncTask.this, result));
- message.sendToTarget();
- }
step 4: 根據step 3,很明顯 handler發送,後緊接著就是消息的處理
[java]
- private static class InternalHandler extends Handler {
-
- @Override
- public void handleMessage(Message msg) {
- AsyncTaskResult result = (AsyncTaskResult) msg.obj;
- switch (msg.what) {
- case MESSAGE_POST_RESULT://通過step 3的Tag,執行改方法;
-
- // There is only one result
- result.mTask.finish(result.mData[0]);
- break;
- case MESSAGE_POST_PROGRESS:
- result.mTask.onProgressUpdate(result.mData);
- break;
- case MESSAGE_POST_CANCEL:
- result.mTask.onCancelled();
- break;
- }
- }
- }
step 5: 根據step 4執行 result.mTask.finish
[java]
- private void finish(Result result) {
- if (isCancelled()) result = null;
- onPostExecute(result);// 注意。。執行了onPostExecute
- mStatus = Status.FINISHED;
- }
至此我們發現上文提到
onPreExecute() ----》doInBackground()------》onPostExecute()基本流程方法都游走一邊
還剩下兩個刷新進度的 : onProgressUpdate()和publishProgress();
[java]
- protected final void publishProgress(Progress... values) {
- sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
- new AsyncTaskResult<Progress>(this, values)).sendToTarget();
- }
從這個方法很容易看出,其實他就是一個Handler消息發送的實現。
網上一般說可以在doInBackground()調用該方法,然後再回過去看handler實例化那段代碼
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
執行了onProgressUpdate()
該類出現了FutureTask以及callable等java中的類。因為手邊沒有java 源碼。沒有細細讀下
整個流程大致如上。