AsyncTask的缺陷和注意事項


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM