Android中AsyncTask應該怎樣使用,會有什麼坑?
04-08
![](http://d.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=82bbf5079122720e7b9beafe4efb2670/79f0f736afc379318119d64ce2c4b74543a91165.jpg)### 1 AsyncTask 回調方法包括下列四個回調方法,他們會在什麼線程中執行呢?doInBackground
推薦閱讀:
publicProgress
preExecutepostExectue通常我們認為:doInBackground :非同步線程publicProgress :主線程preExecute:主線程postExectue:主線程但是如果你真這麼認為,你可能需要為此付出代價了,因為由於安卓系統的某些Bug,使得這些方法的執行線程可能未必如此。
### preExecute 和你調用AsyncTask.execute()在同一個線程如果你在非UI線程裡面調用execute()話,在preExecute中執行UI更新操作,很可能會導致異常:不正確的狀態刷新。### postExectue, publicProgress使用的是sHandler初始化綁定的線程通常情況下的安卓系統都會在主線程中載入AsyncTask類,這樣sHandler默認會綁定到主線程上:這是由於無參數Handler構造函數會使用Looper.myLooper()來進行對象創建,所以它取決於調用者的線程。那麼postExectue和publicProgress默認將在主線程中執行,這並沒有什麼問題。但是,假設系統有bug,它不在主線程中初始化AsyncTask,那麼postExectue中執行某些UI操作將會導致異常。(你可以自己實現一個AsyncTask,然後在非UI線程中載入它,然後看看各個方法的執行對應線程)
### doInBackground 的執行線程這個線程是線程池為你分配的一個線程,也就是說它默認情況下是沒有進行辦法初始化Handler的:因為其不具有Looper.prepare();這就意味著,在極端情況下,這4個回調方法可能在3個不同的線程中執行,並且還都不是主線程。### AsyncTask 線程阻塞的問題。**在doInBackground 執行網路拉取操作是錯誤的寫法!!**因為在安卓3.0 之後,AsyncTask的默認執行器是順序執行的。它會一個一個的執行你的任務,而不是並發的執行這些任務。
除了第一次,之後scheduleNext(); 一定在r.run();後執行,所以即使是並發線程池,也就一個Runnable執行而已。所以,網路拉取操作可能阻塞其他AsyncTask.不建議在doBackground中執行。如果你一定要這麼干,請為AsyncTask分配一個額外的執行器。或者使用v4包裡面的AsyncTask.推薦閱讀: