AsyncTask.cancel()的結束問題,asynctaskcancel
實際項目中有這麼一個問題,使用者進入詳情介面,那麼我們就要網路載入資料並展現在UI上,這個載入用線程或者非同步。
這裡就拿項目中統一用非同步任務來擷取網路資料把。
使用者可能會有這麼一個操作,它在一個商品(說說等)列表中,點擊一個清單項目,進入到相應的詳情介面,這時候,我們會開啟一個非同步任務來擷取網路資料,但是網路差的情況下, 使用者可能就不願意等了,立馬按後退按鈕回到列表,點擊下一個別的清單項目進入詳情介面,發現載入太慢,又按後退鍵,如此反覆,那麼就導致此時有多個非同步任務在執行,或者出現OOM問題,或者出現非同步任務等待問題。
那麼,作為開發人員,我們對應的解決方案,便是在使用者在詳情介面按退出按鈕退回到上一個介面的時候,把沒有執行完的非同步任務給結束掉。
------------------------------------------------------------------------------------------------------------------------------
現在我們發現了這個問題,又有瞭解決方案。那麼就用代碼來實現了。
那麼 取消非同步任務怎麼做?
我一開始這樣做,AsyncTask.cancel(true);
看下參數的定義:
@param mayInterruptIfRunning <tt>true</tt> if the thread executing this * task should be interrupted; otherwise, in-progress tasks are allowed * to complete.
1、如果是true,如果線程執行,則會被打斷
2、如果是false,線程將會被運行執行完成
看到這,很顯然,我們以為.cancel(true)就會結束掉我們開啟的正在執行的非同步任務
但是實際上並沒有結束掉我們想要結束的非同步任務~~
看了些別人對此的解釋:
AsyncTask不會不考慮結果而直接結束一個線程。調用cancel()其實是給AsyncTask設定一個"canceled"狀態。這取決於你去檢查AsyncTask是否已經取消,之後決定是否終止你的操作。對於mayInterruptIfRunning——它所作的只是向運行中的線程發出interrupt()調用。在這種情況下,你的線程是不可中斷的,也就不會終止該線程。
那麼該如何結束線程呢?
可見.cancel()是給AsyncTask設定一個"canceled"的狀態,那麼想要終止非同步任務,就需要在非同步任務當中結束。
@Overridepublic void onProgressUpdate(Integer... value) {// 判斷是否被取消if(isCancelled()) return;.........}@Overrideprotected Integer doInBackground(Void... mgs) {// Task被取消了,馬上退出if(isCancelled()) return null;.......// Task被取消了,馬上退出if(isCancelled()) return null;}...
另外結束非同步任務的條件:
if(loadAsyncVedio!=null && !loadAsyncVedio.isCancelled() && loadAsyncVedio.getStatus() == AsyncTask.Status.RUNNING){ loadAsyncVedio.cancel(true); loadAsyncVedio = null; }
loadAsyncVedio(非同步任務)
如此,便可以有效及時的結束非同步任務