3

私のアクティビティには、以下に示すメソッドAsyncTaskがありdoInBackgroundます。複数のサーバーに対して複数の検索リクエストを行う必要があり、実行を高速化するために、Java を使用ExecutorServiceして同時リクエストを作成しました。

これは問題なく動作しますが、パラメーターとしてメソッドAsyncTaskを呼び出す場合は、実行中のものをすべて停止して終了したいと思います。これは、「戻る」ボタンが押されたときなど、終了時にタスクを停止する必要がある場合に役立ちます。AsyncTask.cancel();truemayInterruptIfRunningActivity

cancel()のメソッドを呼び出すと、メソッドが呼び出されなくなりますが、は完了するまで実行されるAsyncTaskことを読みました。onPostExecutedoInBackground

方法はありますか、私は私の話を中断してCallables、彼らがしていることを強制的に止めさせ、AsyncTask.

簡潔にするために、コードの要約版をここに投稿しましたが、1 つだけでなく、たくさんのCallables.

ありがとう。

  protected ArrayList<Result> doInBackground(final String... strQuery) {

      ArrayList<Result> objResults = new ArrayList<Result>();
      ExecutorService esrExecutor = Executors.newFixedThreadPool(2);
      Set<Callable<ArrayList<Result>>> setCallables = new HashSet<Callable<ArrayList<Result>>>();

      setCallables.add(new Callable<ArrayList<Result>>() {

          public ArrayList<Result> call() throws Exception {

              try {

                  MySearcher objSearcher = new MySearcher(Finder.this.objContext);
                  ArrayList<Result> objResults = new ArrayList<Result>();

                  objResults = objSearcher.doSearch(strQuery[0]);

                  return objResults;

              } catch (Indexer.LoginException e) {
                  return null;
              }

              return null;

          }

      });


      List<Future<ArrayList<Result>>> lstFutures;

      try {

          lstFutures = esrExecutor.invokeAll(setCallables);

          for(Future<ArrayList<Result>> futFuture : lstFutures){
              if (futFuture.get().isEmpty() == false)
                  objResults.addAll(futFuture.get());
          }

      } catch (InterruptedException e) {
          e.printStackTrace();
      } catch (ExecutionException e) {
          e.printStackTrace();
      }

      esrExecutor.shutdown();

      return objResults;

  }
4

3 に答える 3

3

解決策の 1 つは、メソッドをisCancelled()定期的にチェックして、キャンセルされたかどうか、および以前に行っていたことを停止する必要があるかどうかを確認することだと思います。doInBackground()AsyncTask

于 2012-09-19T06:51:02.167 に答える
1

反復して待機する場所は次のとおりです。

   for(Future<ArrayList<Result>> futFuture : lstFutures){
          if (futFuture.get().isEmpty() == false)
              objResults.addAll(futFuture.get());
      }

get()Futureのメソッドは、次の ようにWaits if necessary for the computation to complete, and then retrieves its result. 確認できます。isCancelled()

       for(Future<ArrayList<Result>> futFuture : lstFutures){
           if(isCancelled())
              break;
           else if (futFuture.get().isEmpty() == false)
              objResults.addAll(futFuture.get());
      }
      if(isCancelled())esrExecutor.shutdownNow();
于 2012-09-19T08:06:06.970 に答える
0

別のオプション。たとえば、ループがある場合は、またはdoSearchを使用せずに手動で実行できます。MySearcherクラスには次のものがあります。isCancelledcancel

//in your MySearcher class
private AtomicBoolean cancelled = false;

public ArrayList<Result> doSearch(...){
    while(notFound && !cancelled.get()){
     // keep searching
    }
}

public void cancel(){
    cancelled.set(true);
}

これで、どこからでもキャンセルを呼び出すことができます。

于 2012-09-19T07:14:04.537 に答える