2012-05-20 38 views
0

如果我有一個啓動AsyncTask的按鈕操作。如果我點擊10次按鈕怎麼辦?該任務執行10次,並在後臺運行那麼多?或者任何以前的任務被取消,只是重新開始任務(這將是我期望的行爲)?AsyncTask on button click =任務取消或仍在運行?

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

確實執行了10次。如果你想取消它,你必須手動完成(調用'cancel')。請參閱[取消任務](http://developer.android.com/reference/android/os/AsyncTask.html)。 –

+1

@membersound:雖然你已經接受了具體問題的答案,但這不是一個很好的設計方法。理想情況下,我會禁用第一次點擊按鈕,以防止*用戶點擊10次。如果您希望用戶能夠取消「AsyncTask」,則將按鈕文本更改爲「取消」,以便他們意識到發生了什麼。另一種方法是某種進程對話框,它會從託管按鈕的「活動」中竊取焦點(從而防止多次按下),也可能有一個「取消」或「重新啓動」按鈕。 – Squonk

+0

好吧,這可能是一個好方法。但是對於這種特殊情況,如果任務重新啓動,我確實需要取消任務。 – membersound

回答

1

如果你真的想任務保持到一個單一的執行在如果你這樣做

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。

2

每次單擊按鈕時產生的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); 
} 
+0

非常感謝,幫助了很多!僅供參考,我發現必須調用'lastMyAsyncTask.cancel(true);' – membersound

+1

/編輯:它不起作用!任務仍然在後臺運行,直到它們完成... – membersound

+0

無法中止線程(這包括AsyncTask的doInBackground方法)。看到我的答案在這裏更多http://stackoverflow.com/questions/9119741/listadapter-lifecycle-and-screen-rotation-for-canceling-a-asynctask/9122479#9122479 –