在介紹 AsyncTask 前要先介紹一下 Main Thread , Main Thread 又稱 UI Thread 、 主執行緒,主要是處理畫面,所以若是將所有的工作都往 Main Thread 塞,可能會造成畫面的停頓、延遲,甚至會造成 ANR ( Application Not Responding) 。
而其解套的方法就是今天的主題 AsyncTask (今天就不提另一個 thread 的方法),有一些東西在處理上可能需要花一些時間 (ex.網路請求) ,而就需要再另外開一個執行緒在背後處理這些會耗時的處理。
個人比較喜歡 AsyncTask 原因是,它在其中將各個階段處理的東西分的非常清楚,在寫時只要想清楚什麼東西需要在背景執行,畫面上又有什麼東西需要更新、什麼時候要更新,就可以很清楚地將架構分好。
那我們就先來一個一個了解一下架構。
onPreExecute() : 在 AsyncTask 開始前,需要先宣告事情。
doInBackground() : 真正需要耗時處理的事件,在這裡就不是在主執行緒執行了,已經退到後面的執行緒處理這些耗時操作。
onProgressUpdate() : 有時候並不沒有要等那些耗時操作做玩才對 UI 做更新,例如: 倒數計時,這是要一秒就對 UI 做一次更新而且耗時操作還是要繼續在背後執行,就需要用到這方法對畫面做階段性的更新。
onPostExecute() : 當耗時操作任務完成後,希望做的事情,這邊可以包括對 UI 的操作。
而在第三步 onProgressUpdate() 時,並不一定是哪一種型態,有可能是 Int String …等等,所以在繼承 AsyncTask 時必須得先說好要傳的資料是什麼型態的。
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
其中後面泛型裡的型態便是指定的型態,我們看一下官網文件。
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the background computation.
Result, the type of the result of the background computation.
第一項參數是在任務開始前傳入的型態。
第二項參數是在 doInBackground 傳出,也就是 onProgressUpdate 的傳入型態。
第三項是在該耗時任務完成後,所要傳出的型態。