Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come Android's AsyncTask doesn't implement Future?

In Java, I've gotten used to working with Futures. Now I'm looking at Android, and AsyncTask implements almost all the same methods and covers similar lifecycles. But, if I want to be consistent and use Future all over my code, I have to wrap AsyncTask in a stupid wrapper, cause it doesn't actually implement Future.

All they'd need to add is an isDone() method, which seems like it would be trivial, then add implements Future<Result>. (added later: see my answer below for just how trivial it would be).

Any Android experts know some good reason / obscure bug it might cause why this hasn't been done?

like image 895
user949300 Avatar asked Jul 14 '12 16:07

user949300


People also ask

What is the problem with AsyncTask in Android?

In summary, the three most common issues with AsyncTask are: Memory leaks. Cancellation of background work. Computational cost.

Why is Android AsyncTask deprecated?

This class was deprecated in API level 30. AsyncTask was intended to enable proper and easy use of the UI thread. However, the most common use case was for integrating into UI, and that would cause Context leaks, missed callbacks, or crashes on configuration changes.

Can I still use AsyncTask in Android?

java - The AsyncTask API is deprecated in Android 11.

What is the replacement of AsyncTask in Android?

Alternative 1: Using Executor and Handler The executor will help in performing any task in the background and the handler will help to make UI changes.


2 Answers

From reading the actual code of AsyncTask.java it actually uses a Future task and then some more. A Future is a task that executes asynchronously on the go. An AsyncTask is scheduled on a queue for a single (or pool of) background thread(s).

An AsyncTask is actually more "superior" than a Future task. It does fancy scheduling and optimizations on top of Future's functionality. Just look at the API introduction levels. Future was introduced right from the start API 1.0. The AsyncTask object was introduced in API 3.

An AsyncTask has-a Future task, not is-a Future.

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);
            }
        }
    };
}
like image 158
DritanX Avatar answered Sep 19 '22 16:09

DritanX


I'm still interested in the theoretical reasons "why" not to use AsyncTask for a Future.

But, for the record, I ended up creating my own little class (shown below). Just extend it instead of AsyncTask if you want a Future. IMO, a cleaner way than the @Eng.Fouad idea of accessing the private mFuture within the code. (But thanks for the idea, it got me looking into the source code a bit!) 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();
   }
}
like image 43
user949300 Avatar answered Sep 18 '22 16:09

user949300