AsyncTask用來做background operation,以避免block UI thread造成Application not respond (ANR)
適合做Short operation (Life cycle和Activity綁一起,不會像service在activity destroyed後還在background做)
AsyncTask用ThreadPool對多個Thread進行管理,並且避免thread synchronous問題
Ref : (https://www.ptt.cc/bbs/AndroidDev/M.1390316957.A.0D4.html)
generic types
Params : 執行asyncTask前傳入的參數
Progress : 向UI thread發送目前進度
Result : 任務結束後,將執行結果給onPostExecute至UI thread
由於不是強制一定要使用,可以用下列方式定義:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
The 4 step
1. onPreExecute() : 用於initial所需要的參數,於UI thread。
2. doInBackground(Params...) : 進行需要長時間的operation,於worker thread。
可用publishProgress(Progress...) 來更新進度,當onProgressUpdate時,這些數值將被送到UI thread。
3. onProgressUpdate(Progress...) : 發送執行進度訊息,可對UI thread做操作,能夠直接將progress設置到UI上。
4. doInBackground 執行結束後被invoke,接收doInBackground 的執行結果回傳至UI thread。
Cancelling a task
執行task中隨時可invoke cancel(boolean) ,這時 isCancelled()
return true。
取消成功後invoke onCancelled(Object)
而非 onPostExecute(Object)
所以在執行期間最好不斷檢查 isCancelled()
的狀態
Threading rules
1. AsyncTask必須在UI thread被加載
2. AsyncTask必須在UI thread create
3. execute(Params...) 必須在UI thread被invoke
4. 不可手動調用4 step中的方法
5. task只能run一次 (invoke第二次會拋出exception)
Memory observability
保證callback calls are synchronized :
- Set member fields in the constructor or
onPreExecute()
, and refer to them indoInBackground(Params...)
. - Set member fields in
doInBackground(Params...)
, and refer to them inonProgressUpdate(Progress...)
andonPostExecute(Result)
.
Order of execution
When first introduced, AsyncTasks were executed serially on a single background thread.
Starting with DONUT
, this was changed to a pool of threads allowing multiple tasks to operate in parallel.
Starting with HONEYCOMB
, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[])
with THREAD_POOL_EXECUTOR
.