0

AsyncTask を起動するボタン アクションがあるとします。ボタンを10回クリックするとどうなりますか?タスクは 10 回実行され、バックグラウンドで実行されますか? または、以前のタスクがキャンセルされ、タスクが再開されましたか (それが私の望ましい動作ですか)?

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

2 に答える 2

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);
}
于 2012-05-20T22:59:12.080 に答える
1

タスクを一度に 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 を受け取る可能性がありました。

于 2012-05-21T00:44:14.323 に答える