Отмена AysncTask по-прежнему вызывает onPostExecute()

После вызова AsyncTask.cancel(true)из doInBackground()вместо вызова onCancelled()Android вызывает onPostExecute(). Но согласно документации:

Вызов этого метода приведет к вызову onCancelled(Object)в потоке пользовательского интерфейса после возврата doInBackground(Object[]). Вызов этого Метод гарантирует, что onPostExecute(Object)никогда не будет вызван .

Это ошибка Android?

Дополнительные наблюдения:

  1. Вызов cancel(false)из любого потока работает, как указано в документация.
  2. Вызов cancel(true)из задачи пользовательского интерфейса не вызывает onPostExecute()и не выдает InterruptedException, показанный в трассировках logcat ниже.
  3. Вызов cancel(false/true)из любого потока иногда вызывает onCancelled()даже до возврата doInBackground(). Это явно нарушает документацию , в которой говорится :

. Вызов этого метода приведет к вызову onCancelled(Object). в потоке пользовательского интерфейса после того, как doInBackground(Object[])возвращает .

Код:(Протестировано на устройстве Android 2.2)

protected Void doInBackground(Void... params) {
    Log.d(TAG, "started doInBackground()");
    while (!isCancelled()) {
        boolean ret = cancel(true);
        Log.d(TAG, "cancel() returned: " + ret);
    }
    Log.d(TAG, "returning from doInBackground()");
    return null;
}

Вывод Logcat

04-15 21:38:55.519: D/MyTask(27597): started doInBackground()
04-15 21:38:55.589: W/AsyncTask(27597): java.lang.InterruptedException
04-15 21:38:55.589: W/AsyncTask(27597):     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1254)
04-15 21:38:55.589: W/AsyncTask(27597):     at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:219)
04-15 21:38:55.589: W/AsyncTask(27597):     at java.util.concurrent.FutureTask.get(FutureTask.java:82)
04-15 21:38:55.589: W/AsyncTask(27597):     at android.os.AsyncTask$3.done(AsyncTask.java:196)
04-15 21:38:55.589: W/AsyncTask(27597):     at java.util.concurrent.FutureTask$Sync.innerCancel(FutureTask.java:293)
04-15 21:38:55.589: W/AsyncTask(27597):     at java.util.concurrent.FutureTask.cancel(FutureTask.java:75)
04-15 21:38:55.589: W/AsyncTask(27597):     at android.os.AsyncTask.cancel(AsyncTask.java:325)
04-15 21:38:55.589: W/AsyncTask(27597):     at com.example.test.TestActivity$MyTask.doInBackground(TestActivity.java:31)
04-15 21:38:55.589: W/AsyncTask(27597):     at com.example.test.TestActivity$MyTask.doInBackground(TestActivity.java:1)
04-15 21:38:55.589: W/AsyncTask(27597):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-15 21:38:55.589: W/AsyncTask(27597):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-15 21:38:55.589: W/AsyncTask(27597):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-15 21:38:55.589: W/AsyncTask(27597):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
04-15 21:38:55.589: W/AsyncTask(27597):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
04-15 21:38:55.589: W/AsyncTask(27597):     at java.lang.Thread.run(Thread.java:1096)
04-15 21:38:55.589: D/MyTask(27597): cancel() returned: true
04-15 21:38:55.589: D/MyTask(27597): returning from doInBackground()
04-15 21:38:55.659: D/MyTask(27597): onPostExecute()

7
задан yorkw 16 April 2012 в 00:50
поделиться