blob: b37e176ddb6e7ec718411707b4a99d91a221ab2c [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.os;
18
Tor Norbye83c68962015-03-10 20:55:31 -070019import android.annotation.MainThread;
Makoto Onuki1488a3a2017-05-24 12:25:46 -070020import android.annotation.Nullable;
Andrei Oneadcb67732019-03-18 11:37:25 +000021import android.annotation.UnsupportedAppUsage;
Tor Norbye83c68962015-03-10 20:55:31 -070022import android.annotation.WorkerThread;
Hans Boehm13060ff2019-01-31 17:22:55 -080023
Joe Onorato81de61b2011-01-16 13:04:51 -080024import java.util.ArrayDeque;
Gilles Debunne7f4b6842010-04-27 17:54:21 -070025import java.util.concurrent.Callable;
26import java.util.concurrent.CancellationException;
27import java.util.concurrent.ExecutionException;
Makoto Onuki1488a3a2017-05-24 12:25:46 -070028import java.util.concurrent.Executor;
Gilles Debunne7f4b6842010-04-27 17:54:21 -070029import java.util.concurrent.FutureTask;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import java.util.concurrent.LinkedBlockingQueue;
Hans Boehm573bb792019-02-01 17:52:40 -080031import java.util.concurrent.RejectedExecutionHandler;
32import java.util.concurrent.SynchronousQueue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import java.util.concurrent.ThreadFactory;
Gilles Debunne7f4b6842010-04-27 17:54:21 -070034import java.util.concurrent.ThreadPoolExecutor;
35import java.util.concurrent.TimeUnit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import java.util.concurrent.TimeoutException;
Romain Guy5ba812b2011-01-10 13:33:12 -080037import java.util.concurrent.atomic.AtomicBoolean;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import java.util.concurrent.atomic.AtomicInteger;
39
40/**
Charles Munger0a96c3b2019-10-31 23:17:42 +000041 * <p>AsyncTask was intended to enable proper and easy use of the UI thread. However, the most
42 * common use case was for integrating into UI, and that would cause Context leaks, missed
43 * callbacks, or crashes on configuration changes. It also has inconsistent behavior on different
44 * versions of the platform, swallows exceptions from {@code doInBackground}, and does not provide
45 * much utility over using {@link Executor}s directly.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 *
Romain Guy2c1b8c72012-05-21 10:43:26 -070047 * <p>AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler}
48 * and does not constitute a generic threading framework. AsyncTasks should ideally be
49 * used for short operations (a few seconds at the most.) If you need to keep threads
50 * running for long periods of time, it is highly recommended you use the various APIs
Patrick Tjin72fa3ed2014-02-25 14:52:23 -080051 * provided by the <code>java.util.concurrent</code> package such as {@link Executor},
Romain Guy2c1b8c72012-05-21 10:43:26 -070052 * {@link ThreadPoolExecutor} and {@link FutureTask}.</p>
53 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 * <p>An asynchronous task is defined by a computation that runs on a background thread and
Romain Guy0bbd8d82011-10-11 18:13:37 -070055 * whose result is published on the UI thread. An asynchronous task is defined by 3 generic
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 * types, called <code>Params</code>, <code>Progress</code> and <code>Result</code>,
Gilles Debunne7f4b6842010-04-27 17:54:21 -070057 * and 4 steps, called <code>onPreExecute</code>, <code>doInBackground</code>,
58 * <code>onProgressUpdate</code> and <code>onPostExecute</code>.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 *
Joe Fernandezb54e7a32011-10-03 15:09:50 -070060 * <div class="special reference">
61 * <h3>Developer Guides</h3>
62 * <p>For more information about using tasks and threads, read the
Mark Lu53415ff2016-08-12 13:02:32 -070063 * <a href="{@docRoot}guide/components/processes-and-threads.html">Processes and
Joe Fernandezb54e7a32011-10-03 15:09:50 -070064 * Threads</a> developer guide.</p>
65 * </div>
66 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 * <h2>Usage</h2>
68 * <p>AsyncTask must be subclassed to be used. The subclass will override at least
69 * one method ({@link #doInBackground}), and most often will override a
70 * second one ({@link #onPostExecute}.)</p>
71 *
72 * <p>Here is an example of subclassing:</p>
73 * <pre class="prettyprint">
74 * private class DownloadFilesTask extends AsyncTask&lt;URL, Integer, Long&gt; {
75 * protected Long doInBackground(URL... urls) {
76 * int count = urls.length;
77 * long totalSize = 0;
Hans Boehm13060ff2019-01-31 17:22:55 -080078 * for (int i = 0; i &lt; count; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 * totalSize += Downloader.downloadFile(urls[i]);
80 * publishProgress((int) ((i / (float) count) * 100));
Romain Guy2c1b8c72012-05-21 10:43:26 -070081 * // Escape early if cancel() is called
82 * if (isCancelled()) break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 * }
84 * return totalSize;
85 * }
86 *
87 * protected void onProgressUpdate(Integer... progress) {
88 * setProgressPercent(progress[0]);
89 * }
90 *
91 * protected void onPostExecute(Long result) {
92 * showDialog("Downloaded " + result + " bytes");
93 * }
94 * }
95 * </pre>
96 *
97 * <p>Once created, a task is executed very simply:</p>
98 * <pre class="prettyprint">
99 * new DownloadFilesTask().execute(url1, url2, url3);
100 * </pre>
101 *
102 * <h2>AsyncTask's generic types</h2>
103 * <p>The three types used by an asynchronous task are the following:</p>
104 * <ol>
105 * <li><code>Params</code>, the type of the parameters sent to the task upon
106 * execution.</li>
107 * <li><code>Progress</code>, the type of the progress units published during
108 * the background computation.</li>
109 * <li><code>Result</code>, the type of the result of the background
110 * computation.</li>
111 * </ol>
Owen Lin202f5602009-12-28 15:54:23 +0800112 * <p>Not all types are always used by an asynchronous task. To mark a type as unused,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 * simply use the type {@link Void}:</p>
114 * <pre>
Romain Guy6a1ae642009-05-02 22:52:17 -0700115 * private class MyTask extends AsyncTask&lt;Void, Void, Void&gt; { ... }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 * </pre>
117 *
118 * <h2>The 4 steps</h2>
119 * <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
120 * <ol>
Romain Guy6f931cc2012-10-17 11:06:11 -0700121 * <li>{@link #onPreExecute()}, invoked on the UI thread before the task
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 * is executed. This step is normally used to setup the task, for instance by
123 * showing a progress bar in the user interface.</li>
124 * <li>{@link #doInBackground}, invoked on the background thread
125 * immediately after {@link #onPreExecute()} finishes executing. This step is used
126 * to perform background computation that can take a long time. The parameters
127 * of the asynchronous task are passed to this step. The result of the computation must
128 * be returned by this step and will be passed back to the last step. This step
129 * can also use {@link #publishProgress} to publish one or more units
Romain Guy0bbd8d82011-10-11 18:13:37 -0700130 * of progress. These values are published on the UI thread, in the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 * {@link #onProgressUpdate} step.</li>
Romain Guy0bbd8d82011-10-11 18:13:37 -0700132 * <li>{@link #onProgressUpdate}, invoked on the UI thread after a
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 * call to {@link #publishProgress}. The timing of the execution is
134 * undefined. This method is used to display any form of progress in the user
135 * interface while the background computation is still executing. For instance,
136 * it can be used to animate a progress bar or show logs in a text field.</li>
Romain Guy0bbd8d82011-10-11 18:13:37 -0700137 * <li>{@link #onPostExecute}, invoked on the UI thread after the background
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 * computation finishes. The result of the background computation is passed to
139 * this step as a parameter.</li>
140 * </ol>
Romain Guye95003e2011-01-09 13:53:06 -0800141 *
142 * <h2>Cancelling a task</h2>
143 * <p>A task can be cancelled at any time by invoking {@link #cancel(boolean)}. Invoking
144 * this method will cause subsequent calls to {@link #isCancelled()} to return true.
Romain Guy5ba812b2011-01-10 13:33:12 -0800145 * After invoking this method, {@link #onCancelled(Object)}, instead of
146 * {@link #onPostExecute(Object)} will be invoked after {@link #doInBackground(Object[])}
147 * returns. To ensure that a task is cancelled as quickly as possible, you should always
148 * check the return value of {@link #isCancelled()} periodically from
149 * {@link #doInBackground(Object[])}, if possible (inside a loop for instance.)</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 *
151 * <h2>Threading rules</h2>
152 * <p>There are a few threading rules that must be followed for this class to
153 * work properly:</p>
154 * <ul>
Romain Guy5e9120d2012-01-30 12:17:22 -0800155 * <li>The AsyncTask class must be loaded on the UI thread. This is done
156 * automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.</li>
Romain Guy0bbd8d82011-10-11 18:13:37 -0700157 * <li>The task instance must be created on the UI thread.</li>
158 * <li>{@link #execute} must be invoked on the UI thread.</li>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 * <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
160 * {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
161 * <li>The task can be executed only once (an exception will be thrown if
162 * a second execution is attempted.)</li>
163 * </ul>
Makoto Onukiaa60a022010-08-31 09:42:12 -0700164 *
165 * <h2>Memory observability</h2>
Hans Boehm13060ff2019-01-31 17:22:55 -0800166 * <p>AsyncTask guarantees that all callback calls are synchronized to ensure the following
167 * without explicit synchronizations.</p>
Makoto Onukiaa60a022010-08-31 09:42:12 -0700168 * <ul>
Hans Boehm13060ff2019-01-31 17:22:55 -0800169 * <li>The memory effects of {@link #onPreExecute}, and anything else
170 * executed before the call to {@link #execute}, including the construction
171 * of the AsyncTask object, are visible to {@link #doInBackground}.
172 * <li>The memory effects of {@link #doInBackground} are visible to
173 * {@link #onPostExecute}.
174 * <li>Any memory effects of {@link #doInBackground} preceding a call
175 * to {@link #publishProgress} are visible to the corresponding
176 * {@link #onProgressUpdate} call. (But {@link #doInBackground} continues to
177 * run, and care needs to be taken that later updates in {@link #doInBackground}
178 * do not interfere with an in-progress {@link #onProgressUpdate} call.)
179 * <li>Any memory effects preceding a call to {@link #cancel} are visible
180 * after a call to {@link #isCancelled} that returns true as a result, or
181 * during and after a resulting call to {@link #onCancelled}.
Makoto Onukiaa60a022010-08-31 09:42:12 -0700182 * </ul>
Romain Guy2c1b8c72012-05-21 10:43:26 -0700183 *
184 * <h2>Order of execution</h2>
185 * <p>When first introduced, AsyncTasks were executed serially on a single background
186 * thread. Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
187 * to a pool of threads allowing multiple tasks to operate in parallel. Starting with
188 * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are executed on a single
189 * thread to avoid common application errors caused by parallel execution.</p>
190 * <p>If you truly want parallel execution, you can invoke
191 * {@link #executeOnExecutor(java.util.concurrent.Executor, Object[])} with
192 * {@link #THREAD_POOL_EXECUTOR}.</p>
Charles Munger0a96c3b2019-10-31 23:17:42 +0000193 *
194 * @deprecated Use the standard <code>java.util.concurrent</code> or
195 * <a href="https://developer.android.com/topic/libraries/architecture/coroutines">
196 * Kotlin concurrency utilities</a> instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 */
Charles Munger0a96c3b2019-10-31 23:17:42 +0000198@Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199public abstract class AsyncTask<Params, Progress, Result> {
200 private static final String LOG_TAG = "AsyncTask";
201
Hans Boehm573bb792019-02-01 17:52:40 -0800202 // We keep only a single pool thread around all the time.
203 // We let the pool grow to a fairly large number of threads if necessary,
204 // but let them time out quickly. In the unlikely case that we run out of threads,
205 // we fall back to a simple unbounded-queue executor.
206 // This combination ensures that:
207 // 1. We normally keep few threads (1) around.
208 // 2. We queue only after launching a significantly larger, but still bounded, set of threads.
209 // 3. We keep the total number of threads bounded, but still allow an unbounded set
210 // of tasks to be queued.
211 private static final int CORE_POOL_SIZE = 1;
212 private static final int MAXIMUM_POOL_SIZE = 20;
213 private static final int BACKUP_POOL_SIZE = 5;
214 private static final int KEEP_ALIVE_SECONDS = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 private static final ThreadFactory sThreadFactory = new ThreadFactory() {
217 private final AtomicInteger mCount = new AtomicInteger(1);
218
219 public Thread newThread(Runnable r) {
220 return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
221 }
222 };
223
Hans Boehm573bb792019-02-01 17:52:40 -0800224 // Used only for rejected executions.
225 // Initialization protected by sRunOnSerialPolicy lock.
226 private static ThreadPoolExecutor sBackupExecutor;
227 private static LinkedBlockingQueue<Runnable> sBackupExecutorQueue;
228
229 private static final RejectedExecutionHandler sRunOnSerialPolicy =
230 new RejectedExecutionHandler() {
231 public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
232 android.util.Log.w(LOG_TAG, "Exceeded ThreadPoolExecutor pool size");
233 // As a last ditch fallback, run it on an executor with an unbounded queue.
234 // Create this executor lazily, hopefully almost never.
235 synchronized (this) {
236 if (sBackupExecutor == null) {
237 sBackupExecutorQueue = new LinkedBlockingQueue<Runnable>();
238 sBackupExecutor = new ThreadPoolExecutor(
239 BACKUP_POOL_SIZE, BACKUP_POOL_SIZE, KEEP_ALIVE_SECONDS,
240 TimeUnit.SECONDS, sBackupExecutorQueue, sThreadFactory);
241 sBackupExecutor.allowCoreThreadTimeOut(true);
242 }
243 }
244 sBackupExecutor.execute(r);
245 }
246 };
Joe Onorato81de61b2011-01-16 13:04:51 -0800247
248 /**
Dianne Hackborn96438cd2011-01-25 21:42:37 -0800249 * An {@link Executor} that can be used to execute tasks in parallel.
Charles Munger0a96c3b2019-10-31 23:17:42 +0000250 *
251 * @deprecated Using a single thread pool for a general purpose results in suboptimal behavior
252 * for different tasks. Small, CPU-bound tasks benefit from a bounded pool and queueing, and
253 * long-running blocking tasks, such as network operations, benefit from many threads. Use or
254 * create an {@link Executor} configured for your use case.
Joe Onorato81de61b2011-01-16 13:04:51 -0800255 */
Charles Munger0a96c3b2019-10-31 23:17:42 +0000256 @Deprecated
John Reck2b0ebb32015-11-30 15:45:25 -0800257 public static final Executor THREAD_POOL_EXECUTOR;
258
259 static {
260 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
261 CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
Hans Boehm573bb792019-02-01 17:52:40 -0800262 new SynchronousQueue<Runnable>(), sThreadFactory);
263 threadPoolExecutor.setRejectedExecutionHandler(sRunOnSerialPolicy);
John Reck2b0ebb32015-11-30 15:45:25 -0800264 THREAD_POOL_EXECUTOR = threadPoolExecutor;
265 }
Joe Onorato81de61b2011-01-16 13:04:51 -0800266
Dianne Hackborn96438cd2011-01-25 21:42:37 -0800267 /**
268 * An {@link Executor} that executes tasks one at a time in serial
269 * order. This serialization is global to a particular process.
Charles Munger0a96c3b2019-10-31 23:17:42 +0000270 *
271 * @deprecated Globally serializing tasks results in excessive queuing for unrelated operations.
Dianne Hackborn96438cd2011-01-25 21:42:37 -0800272 */
Charles Munger0a96c3b2019-10-31 23:17:42 +0000273 @Deprecated
Dianne Hackborn96438cd2011-01-25 21:42:37 -0800274 public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275
276 private static final int MESSAGE_POST_RESULT = 0x1;
277 private static final int MESSAGE_POST_PROGRESS = 0x2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278
Andrei Oneadcb67732019-03-18 11:37:25 +0000279 @UnsupportedAppUsage
Joe Onoratod630f102011-03-17 18:42:26 -0700280 private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
Jeff Brownbba231d2014-11-14 15:49:45 -0800281 private static InternalHandler sHandler;
282
Andrei Oneadcb67732019-03-18 11:37:25 +0000283 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 private final WorkerRunnable<Params, Result> mWorker;
Andrei Oneadcb67732019-03-18 11:37:25 +0000285 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 private final FutureTask<Result> mFuture;
287
Andrei Oneadcb67732019-03-18 11:37:25 +0000288 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 private volatile Status mStatus = Status.PENDING;
Romain Guy5ba812b2011-01-10 13:33:12 -0800290
Romain Guy657f5132011-12-05 14:49:33 -0800291 private final AtomicBoolean mCancelled = new AtomicBoolean();
Andrei Oneadcb67732019-03-18 11:37:25 +0000292 @UnsupportedAppUsage
Romain Guy5ba812b2011-01-10 13:33:12 -0800293 private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294
Makoto Onuki1488a3a2017-05-24 12:25:46 -0700295 private final Handler mHandler;
296
Joe Onorato81de61b2011-01-16 13:04:51 -0800297 private static class SerialExecutor implements Executor {
298 final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
299 Runnable mActive;
300
301 public synchronized void execute(final Runnable r) {
302 mTasks.offer(new Runnable() {
303 public void run() {
304 try {
305 r.run();
306 } finally {
307 scheduleNext();
308 }
309 }
310 });
311 if (mActive == null) {
312 scheduleNext();
313 }
314 }
315
316 protected synchronized void scheduleNext() {
317 if ((mActive = mTasks.poll()) != null) {
318 THREAD_POOL_EXECUTOR.execute(mActive);
319 }
320 }
321 }
322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 /**
324 * Indicates the current status of the task. Each status will be set only once
325 * during the lifetime of a task.
326 */
327 public enum Status {
328 /**
329 * Indicates that the task has not been executed yet.
330 */
331 PENDING,
332 /**
333 * Indicates that the task is running.
334 */
335 RUNNING,
336 /**
337 * Indicates that {@link AsyncTask#onPostExecute} has finished.
338 */
339 FINISHED,
340 }
341
Makoto Onuki1488a3a2017-05-24 12:25:46 -0700342 private static Handler getMainHandler() {
Jeff Brownbba231d2014-11-14 15:49:45 -0800343 synchronized (AsyncTask.class) {
344 if (sHandler == null) {
Makoto Onuki1488a3a2017-05-24 12:25:46 -0700345 sHandler = new InternalHandler(Looper.getMainLooper());
Jeff Brownbba231d2014-11-14 15:49:45 -0800346 }
347 return sHandler;
348 }
Dianne Hackborn23fdaf62010-08-06 12:16:55 -0700349 }
350
Makoto Onuki1488a3a2017-05-24 12:25:46 -0700351 private Handler getHandler() {
352 return mHandler;
353 }
354
Joe Onoratod630f102011-03-17 18:42:26 -0700355 /** @hide */
Andrei Oneadcb67732019-03-18 11:37:25 +0000356 @UnsupportedAppUsage
Joe Onoratod630f102011-03-17 18:42:26 -0700357 public static void setDefaultExecutor(Executor exec) {
358 sDefaultExecutor = exec;
359 }
360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 /**
Romain Guy0bbd8d82011-10-11 18:13:37 -0700362 * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 */
364 public AsyncTask() {
Makoto Onuki1488a3a2017-05-24 12:25:46 -0700365 this((Looper) null);
366 }
367
368 /**
369 * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
370 *
371 * @hide
372 */
373 public AsyncTask(@Nullable Handler handler) {
374 this(handler != null ? handler.getLooper() : null);
375 }
376
377 /**
378 * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
379 *
380 * @hide
381 */
382 public AsyncTask(@Nullable Looper callbackLooper) {
383 mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
384 ? getMainHandler()
385 : new Handler(callbackLooper);
386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 mWorker = new WorkerRunnable<Params, Result>() {
388 public Result call() throws Exception {
Romain Guy5ba812b2011-01-10 13:33:12 -0800389 mTaskInvoked.set(true);
Tony Mantler78a8e9d2016-08-05 14:08:06 -0700390 Result result = null;
391 try {
392 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
393 //noinspection unchecked
394 result = doInBackground(mParams);
395 Binder.flushPendingCommands();
Tony Mantler5eb91a42016-09-28 13:55:15 -0700396 } catch (Throwable tr) {
397 mCancelled.set(true);
398 throw tr;
Tony Mantler78a8e9d2016-08-05 14:08:06 -0700399 } finally {
400 postResult(result);
401 }
402 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 }
404 };
405
406 mFuture = new FutureTask<Result>(mWorker) {
407 @Override
408 protected void done() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 try {
Romain Guy657f5132011-12-05 14:49:33 -0800410 postResultIfNotInvoked(get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 } catch (InterruptedException e) {
412 android.util.Log.w(LOG_TAG, e);
413 } catch (ExecutionException e) {
Adrian Roos44bc07d2015-02-11 16:20:26 +0100414 throw new RuntimeException("An error occurred while executing doInBackground()",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 e.getCause());
416 } catch (CancellationException e) {
Romain Guy5ba812b2011-01-10 13:33:12 -0800417 postResultIfNotInvoked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 }
420 };
421 }
422
Romain Guy5ba812b2011-01-10 13:33:12 -0800423 private void postResultIfNotInvoked(Result result) {
424 final boolean wasTaskInvoked = mTaskInvoked.get();
425 if (!wasTaskInvoked) {
426 postResult(result);
427 }
428 }
429
430 private Result postResult(Result result) {
Romain Guy657f5132011-12-05 14:49:33 -0800431 @SuppressWarnings("unchecked")
Jeff Brownbba231d2014-11-14 15:49:45 -0800432 Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
Romain Guy5ba812b2011-01-10 13:33:12 -0800433 new AsyncTaskResult<Result>(this, result));
434 message.sendToTarget();
435 return result;
436 }
437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 /**
439 * Returns the current status of this task.
440 *
441 * @return The current status.
442 */
443 public final Status getStatus() {
444 return mStatus;
445 }
446
447 /**
448 * Override this method to perform a computation on a background thread. The
449 * specified parameters are the parameters passed to {@link #execute}
450 * by the caller of this task.
451 *
Hans Boehm13060ff2019-01-31 17:22:55 -0800452 * This will normally run on a background thread. But to better
453 * support testing frameworks, it is recommended that this also tolerates
454 * direct execution on the foreground thread, as part of the {@link #execute} call.
455 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 * This method can call {@link #publishProgress} to publish updates
Romain Guy0bbd8d82011-10-11 18:13:37 -0700457 * on the UI thread.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 *
459 * @param params The parameters of the task.
460 *
461 * @return A result, defined by the subclass of this task.
462 *
463 * @see #onPreExecute()
464 * @see #onPostExecute
465 * @see #publishProgress
466 */
Tor Norbye83c68962015-03-10 20:55:31 -0700467 @WorkerThread
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468 protected abstract Result doInBackground(Params... params);
469
470 /**
Romain Guy0bbd8d82011-10-11 18:13:37 -0700471 * Runs on the UI thread before {@link #doInBackground}.
Hans Boehm13060ff2019-01-31 17:22:55 -0800472 * Invoked directly by {@link #execute} or {@link #executeOnExecutor}.
473 * The default version does nothing.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 *
475 * @see #onPostExecute
476 * @see #doInBackground
477 */
Tor Norbye83c68962015-03-10 20:55:31 -0700478 @MainThread
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 protected void onPreExecute() {
480 }
481
482 /**
Romain Guy0bbd8d82011-10-11 18:13:37 -0700483 * <p>Runs on the UI thread after {@link #doInBackground}. The
Hans Boehm13060ff2019-01-31 17:22:55 -0800484 * specified result is the value returned by {@link #doInBackground}.
485 * To better support testing frameworks, it is recommended that this be
486 * written to tolerate direct execution as part of the execute() call.
487 * The default version does nothing.</p>
Romain Guye95003e2011-01-09 13:53:06 -0800488 *
489 * <p>This method won't be invoked if the task was cancelled.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 *
491 * @param result The result of the operation computed by {@link #doInBackground}.
492 *
493 * @see #onPreExecute
494 * @see #doInBackground
Romain Guy5ba812b2011-01-10 13:33:12 -0800495 * @see #onCancelled(Object)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 */
497 @SuppressWarnings({"UnusedDeclaration"})
Tor Norbye83c68962015-03-10 20:55:31 -0700498 @MainThread
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 protected void onPostExecute(Result result) {
500 }
501
502 /**
Romain Guy0bbd8d82011-10-11 18:13:37 -0700503 * Runs on the UI thread after {@link #publishProgress} is invoked.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 * The specified values are the values passed to {@link #publishProgress}.
Hans Boehm13060ff2019-01-31 17:22:55 -0800505 * The default version does nothing.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 *
507 * @param values The values indicating progress.
508 *
509 * @see #publishProgress
510 * @see #doInBackground
511 */
512 @SuppressWarnings({"UnusedDeclaration"})
Tor Norbye83c68962015-03-10 20:55:31 -0700513 @MainThread
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 protected void onProgressUpdate(Progress... values) {
515 }
516
517 /**
Romain Guy0bbd8d82011-10-11 18:13:37 -0700518 * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
Romain Guy5ba812b2011-01-10 13:33:12 -0800519 * {@link #doInBackground(Object[])} has finished.</p>
520 *
521 * <p>The default implementation simply invokes {@link #onCancelled()} and
522 * ignores the result. If you write your own implementation, do not call
523 * <code>super.onCancelled(result)</code>.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 *
Romain Guy5ba812b2011-01-10 13:33:12 -0800525 * @param result The result, if any, computed in
526 * {@link #doInBackground(Object[])}, can be null
527 *
528 * @see #cancel(boolean)
529 * @see #isCancelled()
530 */
531 @SuppressWarnings({"UnusedParameters"})
Tor Norbye83c68962015-03-10 20:55:31 -0700532 @MainThread
Romain Guy5ba812b2011-01-10 13:33:12 -0800533 protected void onCancelled(Result result) {
534 onCancelled();
535 }
536
537 /**
538 * <p>Applications should preferably override {@link #onCancelled(Object)}.
539 * This method is invoked by the default implementation of
Hans Boehm13060ff2019-01-31 17:22:55 -0800540 * {@link #onCancelled(Object)}.
541 * The default version does nothing.</p>
Romain Guy5ba812b2011-01-10 13:33:12 -0800542 *
Romain Guy0bbd8d82011-10-11 18:13:37 -0700543 * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
Romain Guy5ba812b2011-01-10 13:33:12 -0800544 * {@link #doInBackground(Object[])} has finished.</p>
545 *
546 * @see #onCancelled(Object)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 * @see #cancel(boolean)
548 * @see #isCancelled()
549 */
Tor Norbye83c68962015-03-10 20:55:31 -0700550 @MainThread
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 protected void onCancelled() {
552 }
553
554 /**
555 * Returns <tt>true</tt> if this task was cancelled before it completed
Romain Guye95003e2011-01-09 13:53:06 -0800556 * normally. If you are calling {@link #cancel(boolean)} on the task,
557 * the value returned by this method should be checked periodically from
558 * {@link #doInBackground(Object[])} to end the task as soon as possible.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559 *
560 * @return <tt>true</tt> if task was cancelled before it completed
561 *
562 * @see #cancel(boolean)
563 */
564 public final boolean isCancelled() {
Romain Guy657f5132011-12-05 14:49:33 -0800565 return mCancelled.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800566 }
567
568 /**
Romain Guye95003e2011-01-09 13:53:06 -0800569 * <p>Attempts to cancel execution of this task. This attempt will
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 * fail if the task has already completed, already been cancelled,
571 * or could not be cancelled for some other reason. If successful,
572 * and this task has not started when <tt>cancel</tt> is called,
Romain Guye95003e2011-01-09 13:53:06 -0800573 * this task should never run. If the task has already started,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 * then the <tt>mayInterruptIfRunning</tt> parameter determines
575 * whether the thread executing this task should be interrupted in
Romain Guye95003e2011-01-09 13:53:06 -0800576 * an attempt to stop the task.</p>
577 *
Romain Guy5ba812b2011-01-10 13:33:12 -0800578 * <p>Calling this method will result in {@link #onCancelled(Object)} being
Hans Boehm13060ff2019-01-31 17:22:55 -0800579 * invoked on the UI thread after {@link #doInBackground(Object[])} returns.
580 * Calling this method guarantees that onPostExecute(Object) is never
581 * subsequently invoked, even if <tt>cancel</tt> returns false, but
582 * {@link #onPostExecute} has not yet run. To finish the
583 * task as early as possible, check {@link #isCancelled()} periodically from
584 * {@link #doInBackground(Object[])}.</p>
585 *
586 * <p>This only requests cancellation. It never waits for a running
587 * background task to terminate, even if <tt>mayInterruptIfRunning</tt> is
588 * true.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 *
590 * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
591 * task should be interrupted; otherwise, in-progress tasks are allowed
592 * to complete.
593 *
594 * @return <tt>false</tt> if the task could not be cancelled,
595 * typically because it has already completed normally;
596 * <tt>true</tt> otherwise
597 *
598 * @see #isCancelled()
Romain Guy5ba812b2011-01-10 13:33:12 -0800599 * @see #onCancelled(Object)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 */
601 public final boolean cancel(boolean mayInterruptIfRunning) {
Romain Guy657f5132011-12-05 14:49:33 -0800602 mCancelled.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 return mFuture.cancel(mayInterruptIfRunning);
604 }
605
606 /**
607 * Waits if necessary for the computation to complete, and then
608 * retrieves its result.
609 *
610 * @return The computed result.
611 *
612 * @throws CancellationException If the computation was cancelled.
613 * @throws ExecutionException If the computation threw an exception.
614 * @throws InterruptedException If the current thread was interrupted
615 * while waiting.
616 */
617 public final Result get() throws InterruptedException, ExecutionException {
618 return mFuture.get();
619 }
620
621 /**
622 * Waits if necessary for at most the given time for the computation
623 * to complete, and then retrieves its result.
624 *
625 * @param timeout Time to wait before cancelling the operation.
626 * @param unit The time unit for the timeout.
627 *
628 * @return The computed result.
629 *
630 * @throws CancellationException If the computation was cancelled.
631 * @throws ExecutionException If the computation threw an exception.
632 * @throws InterruptedException If the current thread was interrupted
633 * while waiting.
634 * @throws TimeoutException If the wait timed out.
635 */
636 public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
637 ExecutionException, TimeoutException {
638 return mFuture.get(timeout, unit);
639 }
640
641 /**
642 * Executes the task with the specified parameters. The task returns
Dianne Hackborn96438cd2011-01-25 21:42:37 -0800643 * itself (this) so that the caller can keep a reference to it.
644 *
645 * <p>Note: this function schedules the task on a queue for a single background
646 * thread or pool of threads depending on the platform version. When first
647 * introduced, AsyncTasks were executed serially on a single background thread.
648 * Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
Romain Guy2c1b8c72012-05-21 10:43:26 -0700649 * to a pool of threads allowing multiple tasks to operate in parallel. Starting
650 * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are back to being
651 * executed on a single thread to avoid common application errors caused
Dianne Hackborn96438cd2011-01-25 21:42:37 -0800652 * by parallel execution. If you truly want parallel execution, you can use
653 * the {@link #executeOnExecutor} version of this method
Romain Guy2c1b8c72012-05-21 10:43:26 -0700654 * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings
655 * on its use.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 *
Romain Guy0bbd8d82011-10-11 18:13:37 -0700657 * <p>This method must be invoked on the UI thread.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 *
659 * @param params The parameters of the task.
660 *
661 * @return This instance of AsyncTask.
662 *
663 * @throws IllegalStateException If {@link #getStatus()} returns either
Romain Guy0bbd8d82011-10-11 18:13:37 -0700664 * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
Romain Guy2c1b8c72012-05-21 10:43:26 -0700665 *
666 * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
667 * @see #execute(Runnable)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 */
Tor Norbye83c68962015-03-10 20:55:31 -0700669 @MainThread
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 public final AsyncTask<Params, Progress, Result> execute(Params... params) {
Joe Onoratod630f102011-03-17 18:42:26 -0700671 return executeOnExecutor(sDefaultExecutor, params);
Joe Onorato81de61b2011-01-16 13:04:51 -0800672 }
673
674 /**
675 * Executes the task with the specified parameters. The task returns
676 * itself (this) so that the caller can keep a reference to it.
Dianne Hackborn96438cd2011-01-25 21:42:37 -0800677 *
678 * <p>This method is typically used with {@link #THREAD_POOL_EXECUTOR} to
679 * allow multiple tasks to run in parallel on a pool of threads managed by
680 * AsyncTask, however you can also use your own {@link Executor} for custom
681 * behavior.
682 *
683 * <p><em>Warning:</em> Allowing multiple tasks to run in parallel from
684 * a thread pool is generally <em>not</em> what one wants, because the order
685 * of their operation is not defined. For example, if these tasks are used
686 * to modify any state in common (such as writing a file due to a button click),
687 * there are no guarantees on the order of the modifications.
688 * Without careful work it is possible in rare cases for the newer version
689 * of the data to be over-written by an older one, leading to obscure data
690 * loss and stability issues. Such changes are best
691 * executed in serial; to guarantee such work is serialized regardless of
692 * platform version you can use this function with {@link #SERIAL_EXECUTOR}.
Joe Onorato81de61b2011-01-16 13:04:51 -0800693 *
Romain Guy0bbd8d82011-10-11 18:13:37 -0700694 * <p>This method must be invoked on the UI thread.
Joe Onorato81de61b2011-01-16 13:04:51 -0800695 *
696 * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a
697 * convenient process-wide thread pool for tasks that are loosely coupled.
698 * @param params The parameters of the task.
699 *
700 * @return This instance of AsyncTask.
701 *
702 * @throws IllegalStateException If {@link #getStatus()} returns either
Romain Guy0bbd8d82011-10-11 18:13:37 -0700703 * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
Romain Guy2c1b8c72012-05-21 10:43:26 -0700704 *
705 * @see #execute(Object[])
Joe Onorato81de61b2011-01-16 13:04:51 -0800706 */
Tor Norbye83c68962015-03-10 20:55:31 -0700707 @MainThread
Joe Onorato81de61b2011-01-16 13:04:51 -0800708 public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
709 Params... params) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710 if (mStatus != Status.PENDING) {
711 switch (mStatus) {
712 case RUNNING:
713 throw new IllegalStateException("Cannot execute task:"
714 + " the task is already running.");
715 case FINISHED:
716 throw new IllegalStateException("Cannot execute task:"
717 + " the task has already been executed "
718 + "(a task can be executed only once)");
719 }
720 }
721
722 mStatus = Status.RUNNING;
723
724 onPreExecute();
725
726 mWorker.mParams = params;
Joe Onorato81de61b2011-01-16 13:04:51 -0800727 exec.execute(mFuture);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728
729 return this;
730 }
731
732 /**
Dianne Hackborn96438cd2011-01-25 21:42:37 -0800733 * Convenience version of {@link #execute(Object...)} for use with
Romain Guy2c1b8c72012-05-21 10:43:26 -0700734 * a simple Runnable object. See {@link #execute(Object[])} for more
735 * information on the order of execution.
736 *
737 * @see #execute(Object[])
738 * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
Joe Onorato81de61b2011-01-16 13:04:51 -0800739 */
Tor Norbye83c68962015-03-10 20:55:31 -0700740 @MainThread
Joe Onorato81de61b2011-01-16 13:04:51 -0800741 public static void execute(Runnable runnable) {
Joe Onoratod630f102011-03-17 18:42:26 -0700742 sDefaultExecutor.execute(runnable);
Joe Onorato81de61b2011-01-16 13:04:51 -0800743 }
744
745 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 * This method can be invoked from {@link #doInBackground} to
Romain Guy0bbd8d82011-10-11 18:13:37 -0700747 * publish updates on the UI thread while the background computation is
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 * still running. Each call to this method will trigger the execution of
Romain Guy0bbd8d82011-10-11 18:13:37 -0700749 * {@link #onProgressUpdate} on the UI thread.
Dmitri Plotnikovbef9c7a2010-06-16 15:38:07 -0700750 *
John Spurlock33900182014-01-02 11:04:18 -0500751 * {@link #onProgressUpdate} will not be called if the task has been
Romain Guy4aaf8ec2010-06-03 10:56:41 -0700752 * canceled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 *
754 * @param values The progress values to update the UI with.
755 *
756 * @see #onProgressUpdate
757 * @see #doInBackground
758 */
Tor Norbye83c68962015-03-10 20:55:31 -0700759 @WorkerThread
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 protected final void publishProgress(Progress... values) {
Romain Guy4aaf8ec2010-06-03 10:56:41 -0700761 if (!isCancelled()) {
Jeff Brownbba231d2014-11-14 15:49:45 -0800762 getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
Romain Guy4aaf8ec2010-06-03 10:56:41 -0700763 new AsyncTaskResult<Progress>(this, values)).sendToTarget();
764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 }
766
767 private void finish(Result result) {
Romain Guye95003e2011-01-09 13:53:06 -0800768 if (isCancelled()) {
Romain Guy5ba812b2011-01-10 13:33:12 -0800769 onCancelled(result);
Romain Guye95003e2011-01-09 13:53:06 -0800770 } else {
771 onPostExecute(result);
772 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 mStatus = Status.FINISHED;
774 }
775
776 private static class InternalHandler extends Handler {
Makoto Onuki1488a3a2017-05-24 12:25:46 -0700777 public InternalHandler(Looper looper) {
778 super(looper);
Jeff Brownbba231d2014-11-14 15:49:45 -0800779 }
780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
782 @Override
783 public void handleMessage(Message msg) {
Jeff Brownbba231d2014-11-14 15:49:45 -0800784 AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 switch (msg.what) {
786 case MESSAGE_POST_RESULT:
787 // There is only one result
788 result.mTask.finish(result.mData[0]);
789 break;
790 case MESSAGE_POST_PROGRESS:
791 result.mTask.onProgressUpdate(result.mData);
792 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 }
794 }
795 }
796
797 private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
798 Params[] mParams;
799 }
800
801 @SuppressWarnings({"RawUseOfParameterizedType"})
802 private static class AsyncTaskResult<Data> {
803 final AsyncTask mTask;
804 final Data[] mData;
805
806 AsyncTaskResult(AsyncTask task, Data... data) {
807 mTask = task;
808 mData = data;
809 }
810 }
811}