http://developer.android.com/reference/android/os/AsyncTask.html
AsyncTask (API level 3,所以幾乎所有目前在市面上流通的 Android 版本皆可使用)
是除 Thread 外的另一種選擇,Android 團隊鼓勵主執行緒(UI thread) 專注於操作 & 畫面的流暢呈現,其餘工作 (如網路資料傳輸、檔案/磁碟/資料存取) 最好都在背景執行;Thread 通常要搭配 Handler 使用,而 AsyncTask 用意在簡化背景執行 Thread 程式碼的撰寫。
如果您預期要執行的工作能在幾秒內完成,就可以選擇使用 AsyncTask,若執行的時間很長,Android 則強烈建議採用 Executor, ThreadPoolExecutor 及 FutureTask。
要使用 AsyncTask,必定要建立一個繼承自 AsyncTask 的子類別,並傳入 3 項資料:
Params -- 要執行 doInBackground() 時傳入的參數,數量可以不止一個
Progress -- doInBackground() 執行過程中回傳給 UI thread 的資料,數量可以不止一個
Rsesult -- 傳回執行結果, 若您沒有參數要傳入,則填入 Void
除了 doInBackground,其他 3 個 method 都是在 UI thread 呼叫
官方範例:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { // 對照前面提到的 3 個傳入的參數 // URL 就是 Params 參數的類別 // Integer 就是 Progress 參數的類別 // Long 就是 Result 參數的類別 protected Long doInBackground(URL... urls) { int count = urls.length; long totalSize = 0; for (int i = 0; i < count; i++) { totalSize += Downloader.downloadFile(urls[i]); // 呼叫 publishProgress() 以更新 UI 畫面, // 可藉由此方式更新畫面上的進度表 publishProgress((int) ((i / (float) count) * 100)); // Escape early if cancel() is called if (isCancelled()) break; } // 將 totalSize 傳給 onPostExecute() return totalSize; } protected void onProgressUpdate(Integer... progress) { // 這裡接收傳入的 progress 值, 並更新進度表畫面 // 參數是 Integer 型態的陣列 // 但是因為在 doInBackground() 只傳一個參數 // 所以以 progress[0] 取得傳入參數 setProgressPercent(progress[0]); } protected void onPostExecute(Long result) { showDialog("Downloaded " + result + " bytes"); } }根據上面的範例,我們要建立一個名為 DownloadFilesTask 的類別,做為下載檔案用, URL 就是將來會傳入 doInBackground 的變數型態,再看 doInBackground() 這個 method 傳入參數寫法
doInBackgound(URL... urls)
表示傳入的 url 可以不止 1 個。
一旦建立好類別,要執行的方法很簡單:
new DownloadFilesTask().execute(url1, url2, url3);
則 DownloadFilesTask() 便會經由 execute() 呼叫 doInBackground(),執行下載 url1, url2, url3 這 3 個檔案,而 doInBackground() 在處理過程中, 透過呼叫 publishProgress() 來傳送資料給 onProgressUpdate(),onProgressUpdate() 更新畫面上的進度表(如果您有在您的 app UI 顯示進度表的話),doInBackground() 執行完畢後,會將結果傳給 onPostExecute()。
注意,若您有工作要放在 onPostExecute() 處理,則 doInBackground() 必定要 return 非 null 的參數,否則 onPostExecute() 內的程式碼不會執行,如下:
doInBackground(Void...arg) { ... ... return null; } // 不會執行 onPostExecute(Void arg) { ... ... }
關於 AsyncTask 的使用,有幾項原則必須遵守:
* AsyncTask 必須在 UI 主執行緒載入(JELLY_BEAN 版本開始會自動執行此事)。
* 必須在 UI 主執行緒建立 AsyncTask。
* 必須在 UI 主執行緒呼叫 AsyncTask.execute()。
* 不要自行呼叫 onPreExecute(),onPostExecute(),doInBackground(), onProgressUpdate()。
* AsyncTask 只能執行一次。
寫得相當清楚
回覆刪除得到許多幫助
Thanks
This article is very good for me,believe also can hope every need guys. thanks again.
回覆刪除請問, 何謂AsyncTask只能執行一次? 不能執行兩次以上嗎?還是有方法可以re-new呢?
回覆刪除官網就是這麼警示的, 我想意思應該是 AsyncTask 不能自己呼叫自己, 重覆執行吧.
回覆刪除在我自己的程式, 通常是 AsyncTask 結束時通知 UI 主執行緒, 有需要時, 再由 UI 主執行緒呼叫.