单击按钮上的AsyncTask =任务已取消或仍在运行?

时间:2012-05-20 22:50:38

标签: java android android-asynctask

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

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

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:1)

如果你真的想让任务一次执行一次,你应该创建一个单线程的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。