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
- package vic.wong.main;
- //模擬網路環境
- public class NetOperator {
- public void operator(){
- try {
- //休眠1秒
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
ProgressBarAsyncTask .java
- package vic.wong.main;
- import android.os.AsyncTask;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- /**
- * 生成該類的物件,並呼叫execute方法之後
- * 首先執行的是onProExecute方法
- * 其次執行doInBackgroup方法
- *
- */
- public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String> {
- private TextView textView;
- private ProgressBar progressBar;
- public ProgressBarAsyncTask(TextView textView, ProgressBar progressBar) {
- super();
- this.textView = textView;
- this.progressBar = progressBar;
- }
- /**
- * 這裡的Integer引數對應AsyncTask中的第一個引數
- * 這裡的String返回值對應AsyncTask的第三個引數
- * 該方法並不執行在UI執行緒當中,主要用於非同步操作,所有在該方法中不能對UI當中的空間進行設定和修改
- * 但是可以呼叫publishProgress方法觸發onProgressUpdate對UI進行操作
- */
- @Override
- protected String doInBackground(Integer... params) {
- NetOperator netOperator = new NetOperator();
- int i = 0;
- for (i = 10; i <= 100; i+=10) {
- netOperator.operator();
- publishProgress(i);
- }
- return i + params[0].intValue() + "";
- }
- /**
- * 這裡的String引數對應AsyncTask中的第三個引數(也就是接收doInBackground的返回值)
- * 在doInBackground方法執行結束之後在執行,並且執行在UI執行緒當中 可以對UI空間進行設定
- */
- @Override
- protected void onPostExecute(String result) {
- textView.setText("非同步操作執行結束" + result);
- }
- //該方法執行在UI執行緒當中,並且執行在UI執行緒當中 可以對UI空間進行設定
- @Override
- protected void onPreExecute() {
- textView.setText("開始執行非同步執行緒");
- }
- /**
- * 這裡的Intege引數對應AsyncTask中的第二個引數
- * 在doInBackground方法當中,,每次呼叫publishProgress方法都會觸發onProgressUpdate執行
- * onProgressUpdate是在UI執行緒中執行,所有可以對UI空間進行操作
- */
- @Override
- protected void onProgressUpdate(Integer... values) {
- int vlaue = values[0];
- progressBar.setProgress(vlaue);
- }
- }