簡體   English   中英

單擊AsyncTask時=任務已取消還是仍在運行?

[英]AsyncTask on button click = task canceled or still running?

如果我有一個啟動AsyncTask的按鈕動作。 如果我單擊按鈕十次該怎么辦? 任務執行10次並在后台運行那么多嗎? 還是取消了以前的任務而只是重新啟動了任務(那是我想要的行為)?

public void myButtonClick(View v) {
   new MyAsyncTask().execute(params);
}

每次單擊按鈕都會生成MyAsyncTask的新實例,這意味着每個任務都會創建並執行直到結束。

如果要停止先前啟動的任務,則必須存儲對上一次啟動的任務的引用,並取消它,例如:

public void myButtonClick(View v) {
    if (this.lastMyAsyncTask != null && this.lastMyAsyncTask.getStatus() != AsyncTask.Status.FINISHED){
        this.lastMyAsyncTask.cancel();
    }
    this.lastMyAsyncTask = new MyAsyncTask();
    this.lastMyAsyncTask.execute(params);
}

如果您確實想一次將任務保持為一次執行,則應創建一個單線程的ThreadPool:

    private ThreadPoolExecutor executor = 
        new ThreadPoolExecutor(1,1, 1, TimeUnit.SECONDS, 
             new SynchronousQueue(), new ThreadPoolExecutor.AbortPolicy());
    private Future<Void> lastSubmitted;
    private ReentrantLock submissionLock = new ReentrantLock();
    ...


    try {
      submissionLock.lock();
      Future<Void> future = 
        executor.submit(new MyAsyncTask()); // assuming this implements Callable<Void>
      lastSubmitted = future;
    }
    catch (RejectedExecutionException e) {
      lastSubmitted.cancel();
      Future<Void> future = 
        executor.submit(new MyAsyncTask()); // assuming this implements Callable<Void>
      lastSubmitted = future;

    }
    finally {
      submissionLock.unlock();
    }

如果按照上面的建議進行操作,則在任務已經運行時嘗試提交該任務,則會得到RejectedExecutionException。 發生這種情況時,您可以取消最后提交的提交,並安排新的執行。 請記住,您的任務必須是可中斷的(請注意InputStream / OutputStream,因為它們不可中斷,請改用Channel對象)。

需要該鎖,以便您序列化提交嘗試。 如果另一個線程在catch塊執行期間提交了任務,則該線程仍可能獲得RejectedExecutionException。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM