shihyingru
3/10/2017 - 6:14 AM

AsyncTask Study

AsyncTask Study

AsyncTask--耗時工作設計

(https://dotblogs.com.tw/hanktom/2016/01/26/191154) (https://dotblogs.com.tw/hanktom/2016/01/26/android-asynctask-practice)

UI執行緒與耗時工作

是除 Thread 外的另一種選擇,Android 團隊鼓勵主執行緒(UI thread) 專注於操作 & 畫面的流暢呈現,其餘工作 (如網路資料傳輸、檔案/磁碟/資料存取) 最好都在背景執行,才能讓應用程式上的元件同時跟使用者做互動;Thread 通常要搭配 Handler 使用,而 AsyncTask 用意在簡化背景執行 Thread 程式碼的撰寫。

預期要執行的工作能在幾秒內完成,就可以選擇使用 AsyncTask,若執行的時間很長,Android 則強烈建議採用 Executor, ThreadPoolExecutor 及 FutureTask。

耗時工作處理-AsyncTask類別

在Android應用程式中若想設計網路連線的程式功能,除了Java原本就有的Thread、Executor等類別外,可使用AsyncTask類別,在字義上,Async是非同步「Asynchronized」的簡寫,它允許開發人員設計能在背景執行的工作,並提供方法能夠與UI thread溝通互動,適合進行較短時間(數秒)的耗時工作。

設計AsyncTask

1.設計AsyncTask的子類別並訂定規範

通常使用AsyncTask是因為它能夠與UI元件互通,因此大都以內部類別方式設計。

public class XX {
class TestTask extends AsyncTask<Void, Void, Void>{
  …
 }
}

使用extends語法繼承AsyncTask之後的Java一般化(Generic)語法必需定義這個類別的傳入值型態、更新進度資料型態與回傳值型態,如下:

AsyncTask<傳入值型態, 更新進度型態, 結果型態>

傳入值型態,Params

代表本工作是否需要傳入資料,若需要,則要先定義資料的型態,此處只能使用參照資料型態,如Integer、String、Boolean等,若不需要任何傳入值可使用Void(大寫的V)類別。

更新進度型態,Progress

在背景工作執行過程中的更新(或回報)資料的型態,例如下載工作的進度可使用Integer(35%)或Float(52.3%)這類回報資料的型態,若不需要更新資料則使用Void類別。

結果(回傳)型態,Result

背景工作完成後回傳的結果資料型態,例如下載工作完成後回傳檔名可使用String類別,或是回傳檔案的大小則使用Long類別,若不需要回傳資料則使用Void類別。
類別定義完成後,該類別內的方法中使用的傳入參數與回傳值還必須與類別義相符合,例如接下來必須實作的doInBackground方法。

2.將工作寫在doInBackground方法中

AsyncTask是抽象類別,因此繼承它的子類別都必須實作其抽象方法,也就是唯一的doInBackground方法,字面上即是在背景工作的方法。
implement 快速鍵:alt + enter

3.產生類別並呼叫execute()

接著可依照需求,在程式碼中呼叫TestTask內部類別的建構子產生物件,再呼叫execute()方法,即可產生另一個執行緒,並在背景執行doInBackground方法內的程式碼,如下:

new TestTask().execute();  

如果後續需要再使用這個物件,也可以將物件儲存後再呼叫execute方法,如下:

TestTask task = new TestTask();
task.execute();

因為TestTask已定義傳入值型態為Void,因此呼叫execute方法可以不用給予參數,若是有定義傳入值型態,則exectute方法內就應該給予值入值。
提示: 呼叫execute方法後,AsyncTask會自動執行必要的方法後自動執行doInBackground方法,而不是由開發人員直接去呼叫doInBackground方法,這樣不會以背景執行緒執行。


AsyncTask 的運作有 4 個階段:

之前 -- onPreExecute -- AsyncTask 執行前的準備工作,例如畫面上顯示進度表,
背景 -- doInBackground -- 實際要執行的程式碼就是寫在這裡,
過程 -- onProgressUpdate -- 用來顯示目前的進度,
之後 -- onPostExecute -- 執行完的結果 - Result 會傳入這裡。

除了 doInBackground,其他 3 個 method 都是在 UI thread呼叫

覆寫方法快速鍵「Ctrl+O」