1. AsyncTask 主要是用來處理后台耗時操作,並將數據更新到主線程的一個工具類。
AsyncTask的執行分為四個步驟,每一步都對應一個回調方法,這些方法不應該由應用程序調用,開發者需要做的就是實現這些方法。
1) 子類化AsyncTask
2) 實現AsyncTask中定義的下面一個或幾個方法
onPreExecute(), 該方法將在執行實際的后台操作前被UI thread調用。可以在該方法中做一些准備工作,如在界面上顯示一個進度條。
doInBackground(Params...), 將在onPreExecute 方法執行后馬上執行,該方法運行在后台線程中。這里將主要負責執行那些很耗時的后台計算工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。
onProgressUpdate(Progress...),在publishProgress方法被調用后,UI thread將調用這個方法從而在界面上展示任務的進展情況,例如通過一個進度條進行展示。
onPostExecute(Result), 在doInBackground 執行完成后,onPostExecute 方法將被UI thread調用,后台的計算結果將通過該方法傳遞到UI thread.
為了正確的使用AsyncTask類,以下是幾條必須遵守的准則:
1) Task的實例必須在UI thread中創建
2) execute方法必須在UI thread中調用
3) 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法
4) 該task只能被執行一次,否則多次調用時將會出現異常
doInBackground方法和onPostExecute的參數必須對應,這兩個參數在AsyncTask聲明的泛型參數列表中指定,第一個為doInBackground接受的參數,第二個為顯示進度的參數,第第三個為doInBackground返回和onPostExecute傳入的參數。
2. Asynctask 存在的問題
1) AsyncTasks的生命周期
Asynctask 的聲明周期和他所在的activity 的生命周期不是一致的, 很多人認為當它生成AsyncTask的Activity終止了,AsyncTask也會終止,這其實是一個誤解。它會以它自有的方式繼續運行,即使你退出了整個應用程序。AsyncTask提前結束的唯一方法是通過調用AsyncTask.cancel()進行取消。
這表明你必須親自管理 AsyncTask的取消操作;否則,由於不必要的后台線程會導致app阻塞的風險,或者內存泄露。當不再需要一個AsyncTask時,一定要取消它,防止在app執行期間引起任何問題。
而且即使調用了cancel() , 也未必能真正地取消任務。因為如果在doInBackgroud里有一個不可中斷的操作,比如BitmapFactory.decodeStream(),那么這個操作會繼續下去。
2)內存泄露
如果AsyncTask被聲明為Activity的非靜態的內部類,那么AsyncTask會保留一個對創建了AsyncTask的Activity的引用。如果Activity已經被銷毀,AsyncTask的后台線程還在執行,它將繼續在內存里保留這個引用,導致Activity無法被回收,引起內存泄露。
3)結果丟失
屏幕旋轉或Activity在后台被系統殺掉等情況會導致Activity的重新創建,之前運行的AsyncTask會持有一個之前Activity的引用,這個引用已經無效,這時調用onPostExecute()再去更新界面將不再生效。
4)並行還是串行
Android 1.6之前的版本,AsyncTask是串行的,在1.6至2.3的版本,改成了並行的。在2.3之后的版本又做了修改,可以支持並行和串行,當想要串行執行時,直接執行execute()方法,如果需要並行執行,則要執行executeOnExecutor(Executor)。
