歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android 異步操作AsyncTask

異步的輕量級實現;
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]
  1. public AsyncTask() {  
  2.   
  3.      mWorker = new WorkerRunnable{//實現線程接扣的線程類。   
  4.          public Result call() {  
  5.              return doInBackground(mParams);//在類似於線程的run方法中調用doInBackground(mParams);   
  6.          }  
  7.      };  
  8.   
  9.      mFuture = new FutureTask(mWorker) {//接受mWorker線程對象,實例化FutureTask類來操作線程。          
  10.  }  
step 2 :在UiThread中調用AsyncTask對象的execute方法。

[java]
  1. public execute(){  
  2.          
  3.         onPreExecute();//此方法中先調用了onPreExecute,也就是我們上文提到的准備工作。   
  4.   
  5.         sExecutor.execute(mFuture);// 然後通過線程池操作構造中我們實例化的runnable對象。   
  6.   
  7.         return this;  
step 3 :根據step 2 可以知道 程序這步執行的應該是mFuture 代碼中的done()

[java]
  1. protected void done() {  
  2.                 Message message;  
  3.                 Result result = null;  
  4.         // 發送消息Tag和 消息處理結果。消息處理結果又用AsyncTaskResult類封裝起來,實例化對象傳遞進去的result就是上面doInBackground方法執行後的結果。   
  5.                 message = sHandler.obtainMessage(MESSAGE_POST_RESULT,  
  6.                         new AsyncTaskResult<Result>(AsyncTask.this, result));  
  7.                 message.sendToTarget();  
  8.             }  
step 4: 根據step 3,很明顯 handler發送,後緊接著就是消息的處理

[java]
  1. private static class InternalHandler extends Handler {  
  2.        
  3.        @Override  
  4.        public void handleMessage(Message msg) {  
  5.            AsyncTaskResult result = (AsyncTaskResult) msg.obj;  
  6.            switch (msg.what) {  
  7.                case MESSAGE_POST_RESULT://通過step 3的Tag,執行改方法;   
  8.   
  9.                    // There is only one result   
  10.                    result.mTask.finish(result.mData[0]);  
  11.                    break;  
  12.                case MESSAGE_POST_PROGRESS:  
  13.                    result.mTask.onProgressUpdate(result.mData);  
  14.                    break;  
  15.                case MESSAGE_POST_CANCEL:  
  16.                    result.mTask.onCancelled();  
  17.                    break;  
  18.            }  
  19.        }  
  20.    }  
step 5: 根據step 4執行  result.mTask.finish

[java]
  1. private void finish(Result result) {  
  2.       if (isCancelled()) result = null;  
  3.       onPostExecute(result);// 注意。。執行了onPostExecute   
  4.       mStatus = Status.FINISHED;  
  5.   }  
至此我們發現上文提到
onPreExecute()  ----》doInBackground()------》onPostExecute()基本流程方法都游走一邊


還剩下兩個刷新進度的 :   onProgressUpdate()和publishProgress();

[java]
  1. protected final void publishProgress(Progress... values) {  
  2.        sHandler.obtainMessage(MESSAGE_POST_PROGRESS,  
  3.                new AsyncTaskResult<Progress>(this, values)).sendToTarget();  
  4.    }  
從這個方法很容易看出,其實他就是一個Handler消息發送的實現。
網上一般說可以在doInBackground()調用該方法,然後再回過去看handler實例化那段代碼
 case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);
                    break;


執行了onProgressUpdate()

    該類出現了FutureTask以及callable等java中的類。因為手邊沒有java  源碼。沒有細細讀下

    整個流程大致如上。

Copyright © Linux教程網 All Rights Reserved