Почему Android AsyncTask не реализует будущее?

В Java я привык работать с Futures. Теперь я смотрю на Android, а AsyncTask реализует почти все те же методы и охватывает аналогичные жизненные циклы. Но, если я хочу быть последовательным и использовать Future по всему моему коду, я должен обернуть AsyncTask в тупой оболочке, потому что он фактически не реализует Future.

Все, что им нужно добавить, это метод isDone(), который, похоже, будет тривиальным, а затем добавьте implements Future<Result>. (добавлено позже: см. мой ответ ниже, насколько это было бы тривиально).

Любые Android-эксперты знают какую-то серьезную причину/непонятную ошибку, которая может привести к тому, что это не было сделано?

Ответ 1

Меня все еще интересуют теоретические причины "почему" не использовать AsyncTask для будущего.

Но для записи я закончил создание своего собственного маленького класса (показано ниже). Просто добавьте его вместо AsyncTask, если вы хотите будущее. ИМО, более чистый путь, чем идея @Eng.Fouad доступа к частному mFuture в коде. (Но, благодаря этой идее, мне немного удалось найти исходный код!) YMMV.

public abstract class FutureAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> implements Future<Result>{

   @Override
   public boolean isDone() {
      return AsyncTask.Status.FINISHED == getStatus();
   }
}

Ответ 2

От чтения фактического кода AsyncTask.java на самом деле используется a Future задача, а затем еще несколько. A Future - это задача, выполняющая асинхронно на ходу. AsyncTask назначается в очереди для одного (или пула) фонового потока.

An AsyncTask на самом деле более "превосходит", чем задача Future. Он действительно нуждается в планировании и оптимизации поверх функциональности Future. Просто взгляните на уровни внедрения API. Future был введен с самого начала API 1.0. Объект AsyncTask был введен в API 3.

В AsyncTask есть задача "Будущее", а не "Будущее".

AsyncTask.java

/**
 * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
 */
public AsyncTask() {
    mWorker = new WorkerRunnable<Params, Result>() {
        public Result call() throws Exception {
            mTaskInvoked.set(true);

            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            //noinspection unchecked
            return postResult(doInBackground(mParams));
        }
    };

    mFuture = new FutureTask<Result>(mWorker) {
        @Override
        protected void done() {
            try {
                postResultIfNotInvoked(get());
            } catch (InterruptedException e) {
                android.util.Log.w(LOG_TAG, e);
            } catch (ExecutionException e) {
                throw new RuntimeException("An error occured while executing doInBackground()",
                        e.getCause());
            } catch (CancellationException e) {
                postResultIfNotInvoked(null);
            }
        }
    };
}

Ответ 3

AsyncTask слишком прост. Он предназначен для коротких задач, которые могут занимать несколько секунд, но для которых вы не хотите блокировать поток пользовательского интерфейса. Если вам действительно нужен Future, ваша задача, вероятно, слишком сложна для AsyncTask.

Вы можете проверить статус AsyncTask, вызвав getStatus(). Это вернет перечисление, которое может быть одним из Status.PENDING, Status.RUNNING или Status.FINISHED.