標籤:
轉自:Android AsyncTask完全解析,帶你從源碼的角度徹底理解
另外一篇比較詳細的博文:http://blog.csdn.net/liuhe688/article/details/6532519
AsyncTask的基本用法
首先來看一下AsyncTask的基本用法,由於AsyncTask是一個抽象類別,所以如果我們想使用它,就必須要建立一個子類去繼承它。在繼承時我們可以為AsyncTask類指定三個泛型參數,這三個參數的用途如下:
1. Params
在執行AsyncTask時需要傳入的參數,可用於在背景工作中使用。
2. Progress
背景工作執行時,如果需要在介面上顯示當前的進度,則使用這裡指定的泛型作為進度單位。
3. Result
當任務執行完畢後,如果需要對結果進行返回,則使用這裡指定的泛型作為傳回值類型。
因此,一個最簡單的自訂AsyncTask就可以寫成如下方式:
1 class DownloadTask extends AsyncTask<Void, Integer, Boolean> {2 ……3 }
這裡我們把AsyncTask的第一個泛型參數指定為Void,表示在執行AsyncTask的時候不需要傳入參數給背景工作。第二個泛型參數指定為Integer,表示使用整型資料來作為進度顯示單位。第三個泛型參數指定為Boolean,則表示使用布爾型資料來反饋執行結果。
當然,目前我們自訂的DownloadTask還是一個空任務,並不能進行任何實際的操作,我們還需要去重寫AsyncTask中的幾個方法才能完成對任務的定製。經常需要去重寫的方法有以下四個:
1. onPreExecute()
這個方法會在背景工作開始執行之間調用,用於進行一些介面上的初始化操作,比如顯示一個進度條對話方塊等。
2. doInBackground(Params...)
這個方法中的所有代碼都會在子線程中運行,我們應該在這裡去處理所有的耗時任務。任務一旦完成就可以通過return語句來將任務的執行結果進行返回,如果AsyncTask的第三個泛型參數指定的是Void,就可以不返回任務執行結果。注意,在這個方法中是不可以進行UI操作的,如果需要更新UI元素,比如說反饋當前任務的執行進度,可以調用publishProgress(Progress...)方法來完成。
3. onProgressUpdate(Progress...)
當在背景工作中調用了publishProgress(Progress...)方法後,這個方法就很快會被調用,方法中攜帶的參數就是在背景工作中傳遞過來的。在這個方法中可以對UI進行操作,利用參數中的數值就可以對介面元素進行相應的更新。
4. onPostExecute(Result)
當背景工作執行完畢並通過return語句進行返回時,這個方法就很快會被調用。返回的資料會作為參數傳遞到此方法中,可以利用返回的資料來進行一些UI操作,比如說提醒任務執行的結果,以及關閉掉進度條對話方塊等。
因此,一個比較完整的自訂AsyncTask就可以寫成如下方式:
1 class DownloadTask extends AsyncTask<Void, Integer, Boolean> { 2 3 @Override 4 protected void onPreExecute() { 5 progressDialog.show(); 6 } 7 8 @Override 9 protected Boolean doInBackground(Void... params) {10 try {11 while (true) {12 int downloadPercent = doDownload();13 publishProgress(downloadPercent);14 if (downloadPercent >= 100) {15 break;16 }17 }18 } catch (Exception e) {19 return false;20 }21 return true;22 }23 24 @Override25 protected void onProgressUpdate(Integer... values) {26 progressDialog.setMessage("當前下載進度:" + values[0] + "%");27 }28 29 @Override30 protected void onPostExecute(Boolean result) {31 progressDialog.dismiss();32 if (result) {33 Toast.makeText(context, "下載成功", Toast.LENGTH_SHORT).show();34 } else {35 Toast.makeText(context, "下載失敗", Toast.LENGTH_SHORT).show();36 }37 }38 }
這裡我們類比了一個下載任務,在doInBackground()方法中去執行具體的下載邏輯,在onProgressUpdate()方法中顯示當前的下載進度,在onPostExecute()方法中來提示任務的執行結果。如果想要啟動這個任務,只需要簡單地調用以下代碼即可:
1 new DownloadTask().execute();
以上就是AsyncTask的基本用法,怎麼樣,是不是感覺在子線程和UI線程之間進行切換變得靈活了很多?我們並不需求去考慮什麼非同步訊息處理機制,也不需要專門使用一個Handler來發送和接收訊息,只需要調用一下publishProgress()方法就可以輕鬆地從子線程切換到UI線程了。
以上只是實現了AsyncTask的用法,具體的實現機制,需要參考大神郭霖的部落格了。http://blog.csdn.net/guolin_blog/article/details/11711405
Android開發之非同步訊息處理機制AsyncTask