0

如果我有一个启动 AsyncTask 的按钮操作。如果我点击按钮 10 次怎么办?任务是否执行 10 次并在后台运行那么多?或者是否有任何先前的任务被取消并且只是重新启动了任务(这将是我想要的行为)?

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

2 回答 2

2

每次单击按钮都会生成一个新的 your 实例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);
}
于 2012-05-20T22:59:12.080 回答
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。

于 2012-05-21T00:44:14.323 回答