AsyncTask的缺陷和注意事項

1. AsyncTask 主要是用來處理後臺耗時操做,並將數據更新到主線程的一個工具類。app

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 存在的問題code

1) AsyncTasks的生命週期生命週期

Asynctask 的聲明週期和他所在的activity 的生命週期不是一致的, 不少人認爲當它生成AsyncTask的Activity終止了,AsyncTask也會終止,這實際上是一個誤解。它會以它自有的方式繼續運行,即便你退出了整個應用程序。AsyncTask提早結束的惟一方法是經過調用AsyncTask.cancel()進行取消。內存

這代表你必須親自管理 AsyncTask的取消操做;不然,因爲沒必要要的後臺線程會致使app阻塞的風險,或者內存泄露。當再也不須要一個AsyncTask時,必定要取消它,防止在app執行期間引發任何問題。開發

並且即便調用了cancel() , 也未必能真正地取消任務。由於若是在doInBackgroud裏有一個不可中斷的操做,好比BitmapFactory.decodeStream(),那麼這個操做會繼續下去。it

 

2)內存泄露thread

 

若是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)。

相關文章
相關標籤/搜索