0

まず、下手な英語でごめんなさい。私はAndroid 2.3を持っているので、順次実行する代わりに「本物の」並列AsyncTaskがあります(Android 3.0以降)。いくつかの AsyncTasks があり、それぞれが onPostExecute() コールバックを実行します (UI スレッドで実行されることはわかっています)。並列の AsyncTask が 2 つしかなく、最初のタスクがジョブを完了すると、コールバック onPostExecute() が呼び出されるとします。onPostExecute() (最初の AsyncTask から) メソッドが UI スレッドで実行されている間に、2 番目のタスクがその onPostExecute() メソッドを呼び出して、最初の AsyncTask の onPostExecute() の現在の実行を中断する可能性はありますか?

// UPDATED 今、コードで説明します:

// AsyncTask1
onPostExecute(Result result) {
    activity->processResult1(result);
} 

// AsyncTask2
onPostExecute(Result result) {
    activity->processResult2(result);

AsyncTask1 がジョブを終了し、processResult1() が非常に長時間実行されるメソッドであるとします。UI スレッドで processResult1() を実行している間に、AsyncTask2 はそのジョブを終了します。今、何が起きた?

  1. processResult1() は processResult2() によって中断されます
  2. processResult2() は processResult1() が終了するまで待機します
4

3 に答える 3

0

これを読んでください:(ここのアンドロイドドキュメントからコピー):

最初に導入されたとき、AsyncTasks は単一のバックグラウンド スレッドでシリアルに実行されました。DONUT 以降、これはスレッドのプールに変更され、複数のタスクが並行して動作できるようになりました。HONEYCOMB 以降、並列実行によって発生する一般的なアプリケーション エラーを回避するために、タスクは単一のスレッドで実行されます。

本当に並列実行が必要な場合は、THREAD_POOL_EXECUTOR を使用して executeOnExecutor(java.util.concurrent.Executor, Object[]) を呼び出すことができます。

複数の AsyncTask を実行する場合、デバイスが DONUT<= device api < HONEYCOMB であれば、それらは同時に実行されます。これは、Android が単一のスレッドではなく複数のバックグラウンド スレッドを使用して、これらのバージョンで AsyncTasks を実行するためです。結果として、タスクは同時に実行されるため、GUI スレッドで必ずしも開始された順序で実行されるとは限りません。しかし、これは経験に基づいた推測であり、確かなことはわかりません。

デバイス ソフトウェアが < DONUT または >= HONEYCOMB の場合、操作は開始された順序で GUI スレッドにポストされます。これは、これらのバージョンではすべての AsyncTask が 1 つのバックグラウンド スレッドで実行されるため、独立して実行されないためです。

さて、あなたが尋ねていると思う部分について:

すべてのバージョンで、ある AsyncTask を別の AsyncTask からキャンセルできます。ただし、バージョン >=DONUT および < HONEYCOMB では、AsyncTasks が同時に実行されるため、中断しようとするタスクが既に完了している可能性があります。

ただし、GUI スレッドは 1 つのスレッドであるため、2 つのタスクを同時に実行することはできません。1 つの AyncTask がフラグをスローして、完了した後に他の AsyncTask がその GUI 更新を実行するのを防ぐことができますが、GUI スレッドでのタスクの存続期間が短いため、これは悪いアプローチです。

于 2013-07-07T18:29:25.120 に答える