Почему 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
.