[英]Android AsyncTask won't stop when cancelled, why?
我在Activity的onPause生命周期事件中關閉了一個AsyncTask,因此當有人離開應用程序時它不會運行,但它會繼續運行,盡管如此。 我添加了一些跟蹤,這個片段顯示了問題。
Trace.d(TAG,"Task state: " + myTask.getStatus() );
myTask.cancel(true);
Trace.d(TAG,"Task state: " + myTask.getStatus() );
輸出:
Task state: RUNNING
Task state: RUNNING
為什么cancel()方法對任務的狀態沒有任何影響? 我注意到文檔說取消方法將“嘗試”停止任務,但在什么情況下會失敗? 該任務肯定正在運行,因為它每十秒輸出一次日志輸出,如上所示,其狀態將返回為運行狀態。
更新:我添加了跟蹤以顯示isCancelled()狀態,並且會更改。 所以取消(true)的調用是將取消狀態從false更改為true,但顯然對Status沒有影響,或者停止線程。
請記住,您的Activity和AsyncTask是兩個獨立的線程。 因此,即使取消AsyncTask,取消任務的代碼也可能無法運行! 這就是為什么即使在修復bug之后你仍然看到AsyncTask仍在運行的原因。 在AsyncTask中的doInBackground()
完成之前,我認為狀態不會改變。 (因此,請確保您正在檢查isCancelled()
並在取消時提前返回!)
thread.cancel(true);
僅在AsyncTask類中設置變量。 你需要做的是在你的后台任務中實現一個循環,如果你還沒有。 然后檢查並中斷循環,如果每次迭代取消為真。
@Override
protected Void doInBackground(Void... params) {
synchronized(this) {
for(int i = 0; i < 9000; i++) {
if(thread.isCancelled()) break;
// do stuff
}
}
}
然后只需將其設置為取消,只要您需要它停止。 然后它將在下一次迭代之前停止。
@Override
public void onStop() {
super.onStop();
thread.cancel(true);
}
@Override
public void onDestroy() {
super.onDestroy();
thread.cancel(true);
}
我深入挖掘並記住我的線程正在調用包含此內容的寫得很差的方法,在我需要取消的內部生成另一個線程:
public static void haveASleep(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (InterruptedException ie)
{
Trace.w(TAG,"Sleep interrupted");
}
}
所以發生的事情是AsyncTask線程調用此方法等待一段時間,並且在睡眠期間,在AsyncTask上發生cancel()方法調用,這會導致線程休眠中出現異常。 我的代碼無益地捕獲並吸收了該異常,而不是使用它來關閉AsyncTask。
解決方案是在睡眠中尋找異常,如果它被拋出,則靜靜地退出線程。 該應用程序現在按預期工作,但...
cancel()方法調用之后的狀態仍然是RUNNING,但我懷疑這是因為此時它仍然在運行,並且操作系統尚未將其關閉。 我不知道這是不是真的,但那是我最好的估計。
另一個可能的缺陷是檢查您是否遇到此問題:
確保您沒有啟動兩個AsyncTasks。
即使您知道取消是如何工作的,也很難確定您的線程將在什么狀態下停止。 所以我建議你實現自己的安全方法來阻止你的線程,這樣你就可以確定你停止了什么狀態,你確定沒有內存泄漏等等。從更多信息如何在java中停止一個線程安全檢查這個線程如何在java中快速,干凈地中止線程?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.