Android - 強力取消AsyncTask



2 Answers

AsyncTask上調用cancel() 。 這是否會實際取消任何東西取決於你正在做什麼。 引用羅曼蓋伊:

如果調用cancel(true),則會向後台線程發送一個中斷,這可能有助於中斷任務。 否則,您應該確保在doInBackground()方法中定期檢查isCancelled()。 您可以在code.google.com/p/shelves上查看此示例。

Question

我在我的一個活動中實現了AsyncTask:

 performBackgroundTask asyncTask = new performBackgroundTask();
 asyncTask.execute();

現在,我需要實現“取消”按鈕功能,所以我必須停止執行正在運行的任務。 我不知道如何停止運行任務(後台任務)。

所以請建議我,如何有力地取消AsyncTask?

更新:

我發現了相同的Cancel()方法,但我發現調用cancel(boolean mayInterruptIfRunning)並不一定會停止執行後台進程。 似乎發生的一切是AsyncTask將執行onCancelled(),並且在完成時不會運行onPostExecute()。




我們的全局AsyncTask類變量

LongOperation LongOperationOdeme = new LongOperation();

和KEYCODE_BACK動作中斷AsyncTask

   @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            LongOperationOdeme.cancel(true);
        }
        return super.onKeyDown(keyCode, event);
    }

這個對我有用。




註釋中提到的isCancelled() always returns false even i call asynctask.cancel(true); 如果我關閉我的應用程序,尤其有害,但AsyncTask繼續工作。

為了解決這個問題,我通過以下方式修改了Jacob Nordfalk代碼的建議:

protected Object doInBackground(Object... x) {
    while (/* condition */) {
      // work...
      if (isCancelled() || (FlagCancelled == true)) break;
    }
    return null;
 }

並在主要活動中添加以下內容:

@Override
protected void onStop() {
    FlagCancelled = true;
    super.onStop();
}

由於我的AsyncTask是其中一個視圖的私有類,因此需要該標誌的getter或setter來通知AsyncTask當前實際的標誌值。

我的多次測試(AVD Android 4.2.2,Api 17)已經表明,如果AsyncTask已經在執行其doInBackground ,那麼isCancelled() )對任何取消它的嘗試都沒有任何反應(即繼續為假),例如在mViewGroup.removeAllViews();期間mViewGroup.removeAllViews(); 或者在MainActivityOnDestroy期間,每個都會導致視圖分離

   @Override 
   protected  void  onDetachedFromWindow() { 
    mAsyncTask.cancel(false); // and the same result with mAsyncTask.cancel(true);
    super.onDetachedFromWindow(); 
   } 

如果由於引入的FlagCancelled設法強制停止doInBackground() ,則onPostExecute() ,但是不調用onPostExecute() onCancelled()onCancelled(Void result) (因為API級別11)。 (我不知道為什麼,因為它們應該被調用而onPostExecute()不應該,“Android API doc說:調用cancel()方法保證永遠不會調用onPostExecute(Object)。” - IdleSun回答類似的問題 ) 。

另一方面,如果相同的AsyncTask在取消之前沒有啟動其doInBackground() ,那麼一切正常, isCancelled()更改為true,我可以檢查

@Override
    protected void onCancelled() {
        Log.d(TAG, String.format("mAsyncTask - onCancelled: isCancelled = %b, FlagCancelled = %b", this.isCancelled(), FlagCancelled ));
    super.onCancelled();
}



Related