及時取消代碼中的AsyncTask


在一個Activity頁面,如果發起了AsyncTask任務,然后頁面離開/銷毀了,此時如果doInBackground沒執行完,會有兩個問題:

1, AsyncTask白白消耗資源,結果已經用不上了,因為UI也不在;

2, AsyncTask如果聲明為Activity的內部類,會持有Activity這個宿主類,導致Activity內存泄露。

所以一定要在Activity onDestory的時候cancel掉AsyncTask任務。

怎么從一個App的架構層面來約束所有的業務模塊都自動做這個事情呢?

1, 自定義一個AutoCancelAsyncTask,繼承AsyncTask,定義一個成員變量,叫id。

2, 定義一個TaskManager單例類,維護一個AutoCancelAsyncTask隊列。

3, 在AutoCancelAsyncTask的構造方法中,把自己加到TaskManager的隊列。

4, 在AutoCancelAsyncTask中重寫onCancelled和onPostExcute方法,調用TaskManager的一個方法,這個方法從隊列中刪除id對應的AutoCancelAsyncTask。

5, 定義BaseActivity,這個類生成一個唯一標識自己的id。

6, 業務Activity都繼承BaseActivity,發起的AsyncTask都繼承AutoCancelAsyncTask,並傳入activity的唯一id給AutoCancelAsyncTask的id。

7, 在BaseActivity的onDestory方法中調用TaskManager的一個方法,這個方法接收當前activity的id,然后遍歷隊列,找到與傳入的id相同的AutoCancelAsyncTask,然后調用其cancel方法。

PS:

1, 如果害怕業務子類重寫AutoCancelAsyncTask的onCancelled或者onPostExcute的時候不調用super導致沒從隊列中刪除這個Task,可以final這兩個方法,給子類另外留兩個接口出來;

2, 假如doInBackground中是個慢操作任務,調用cancel基本都能取消掉提現結束;但如果是個循環,沒用! 所以好的做法是在循環的條件判斷中假如this.isCancelled()判斷,如果是true,直接break循環。


免責聲明!

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



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