1. 程式人生 > >android開發非同步載入網路資料AsyncTask的使用

android開發非同步載入網路資料AsyncTask的使用

一、非同步任務載入網路資料:

在android中提供了一個非同步任務的類AsyncTask,簡單來說,這個類中的任務是執行在後臺執行緒中的,並可以將結果放到UI執行緒中進行處理,它定義了三種泛型,分別是Params、Progress和Result,分別表示請求的引數、任務的進度和獲得的結果資料。

1、使用原因:

1)其中使用了執行緒池技術,而且其中的方法很容易實現呼叫。

2)可以呼叫相關的方法,在開啟子執行緒前和後,進行介面的更新。

3)一旦任務多了,不用每次都new新的執行緒,可以直接使用。

2、執行的順序:

onPreExecute()【執行前開啟】---》doInBackground(Object... params)---》onProgressUpdate(Object... values)---》onPostExecute(Object result)

3、執行過程:

當一個非同步任務開啟後,執行過程如下:

1)onPreExecute();

這個方法是執行在主執行緒中的。這不操作是用於準備好任務的,作為任務載入的準備工作。建議在這個方法中彈出一個對話方塊。

   2)doInBackground(Object... params);

這個方法是執行在子執行緒中的。在onPreExecute();方法執行完後會立即執行這個方法在方法中可以執行耗時的操作。需要將請求的引數傳遞進來,傳送給伺服器,並將或取到的資料返回,資料會傳給最後一步中;這些值都將被放到主執行緒中,也可以不斷地傳遞給下一步的onProgressUpdate();中進行更新。可以通過不斷地呼叫publishProgress();將資料(或進度)不斷傳遞給onProgressUpdate();方法,進行不斷更新介面。

3)onProgressUpdate(Object... values);

這個方法是執行在主執行緒中的。publishProgress();在doInBackground(Object... params);中被呼叫後,才開始執行的這個方法,他在何時被開啟的是不確定的,在執行這個方法的過程中,doInBackground(Object... params);方法是仍在執行的即子執行緒還在執行著。

4)onPostExecute(Object result);

這個方法是執行在主執行緒中的。當後臺的子執行緒執行完畢後才呼叫的這個方法。doInBackground(Object... params);返回的結果會作為引數被傳遞過來。可以在這個方法中進行資料處理介面更新的操作。

 5)execute();

    最後建立 AsyncTask的自定義類,開啟非同步任務。asyncTask.execute(params);

4、實現原理:

1)執行緒池的建立:

在建立了AsyncTask的時候,會預設建立一個執行緒池ThreadPoolExecutor,並預設創建出5個執行緒放入到執行緒池中,最多可放128個執行緒;且這個執行緒池是公共的唯一一份兒

2)任務的執行:

在execute();中,會執行run方法,當執行完run方法後,會呼叫scheduleNext();不斷的從雙端佇列中輪詢,獲取下一個任務並據需放到一個子執行緒中執行,知道非同步任務執行完成。

3)訊息的處理:

在執行完onPreExecute()方法之後執行了doInBackground(Object... params);方法,然後就不斷的傳送請求獲取資料;在這個AsyncTask中 維護了一個InternalHandler的類,這個類是繼承Handler的,獲取的資料是通過Handler進行處理和傳送的。在q其handlerMessage();方法中, 將訊息傳給onProgressUpdate(Object... values);進行進度的更新,也就可以將結果傳送到主執行緒中進行介面的更新了。

5、需要注意的是:

1)這個AsyncTask類必須有子類進行呼叫

2)雖然是放在子執行緒中執行的操作,但是不建議做特別耗時的操作,如果操作過於耗時建議使用執行緒池ThreadPoolExecutor和FutureTask

貼出程式碼:

NetOperator.java

  1. package vic.wong.main;  
  2. //模擬網路環境  
  3. public class NetOperator {  
  4.     public void operator(){  
  5.         try {  
  6.             //休眠1秒  
  7.             Thread.sleep(1000);  
  8.         } catch (InterruptedException e) {  
  9.             // TODO Auto-generated catch block  
  10.             e.printStackTrace();  
  11.         }  
  12.     }  
  13. }  

ProgressBarAsyncTask .java 

  1. package vic.wong.main;  
  2. import android.os.AsyncTask;  
  3. import android.widget.ProgressBar;  
  4. import android.widget.TextView;  
  5. /**  
  6.  * 生成該類的物件,並呼叫execute方法之後  
  7.  * 首先執行的是onProExecute方法  
  8.  * 其次執行doInBackgroup方法  
  9.  *  
  10.  */  
  11. public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String> {  
  12.     private TextView textView;  
  13.     private ProgressBar progressBar;  
  14.     public ProgressBarAsyncTask(TextView textView, ProgressBar progressBar) {  
  15.         super();  
  16.         this.textView = textView;  
  17.         this.progressBar = progressBar;  
  18.     }  
  19.     /**  
  20.      * 這裡的Integer引數對應AsyncTask中的第一個引數   
  21.      * 這裡的String返回值對應AsyncTask的第三個引數  
  22.      * 該方法並不執行在UI執行緒當中,主要用於非同步操作,所有在該方法中不能對UI當中的空間進行設定和修改  
  23.      * 但是可以呼叫publishProgress方法觸發onProgressUpdate對UI進行操作  
  24.      */  
  25.     @Override  
  26.     protected String doInBackground(Integer... params) {  
  27.         NetOperator netOperator = new NetOperator();  
  28.         int i = 0;  
  29.         for (i = 10; i <= 100; i+=10) {  
  30.             netOperator.operator();  
  31.             publishProgress(i);  
  32.         }  
  33.         return i + params[0].intValue() + "";  
  34.     }  
  35.     /**  
  36.      * 這裡的String引數對應AsyncTask中的第三個引數(也就是接收doInBackground的返回值)  
  37.      * 在doInBackground方法執行結束之後在執行,並且執行在UI執行緒當中 可以對UI空間進行設定  
  38.      */  
  39.     @Override  
  40.     protected void onPostExecute(String result) {  
  41.         textView.setText("非同步操作執行結束" + result);  
  42.     }  
  43.     //該方法執行在UI執行緒當中,並且執行在UI執行緒當中 可以對UI空間進行設定  
  44.     @Override  
  45.     protected void onPreExecute() {  
  46.         textView.setText("開始執行非同步執行緒");  
  47.     }  
  48.     /**  
  49.      * 這裡的Intege引數對應AsyncTask中的第二個引數  
  50.      * 在doInBackground方法當中,,每次呼叫publishProgress方法都會觸發onProgressUpdate執行  
  51.      * onProgressUpdate是在UI執行緒中執行,所有可以對UI空間進行操作  
  52.      */  
  53.     @Override  
  54.     protected void onProgressUpdate(Integer... values) {  
  55.         int vlaue = values[0];  
  56.         progressBar.setProgress(vlaue);  
  57.     }  
  58. }