如果我有一个启动 AsyncTask 的按钮操作。如果我点击按钮 10 次怎么办?任务是否执行 10 次并在后台运行那么多?或者是否有任何先前的任务被取消并且只是重新启动了任务(这将是我想要的行为)?
public void myButtonClick(View v) {
new MyAsyncTask().execute(params);
}
如果我有一个启动 AsyncTask 的按钮操作。如果我点击按钮 10 次怎么办?任务是否执行 10 次并在后台运行那么多?或者是否有任何先前的任务被取消并且只是重新启动了任务(这将是我想要的行为)?
public void myButtonClick(View v) {
new MyAsyncTask().execute(params);
}
每次单击按钮都会生成一个新的 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);
}
如果你真的想让任务一次只执行一次,你应该创建一个单线程线程池:
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。