19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.os;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1981de61bfddceba0eb77b3aacea317594b0f1de49Joe Onoratoimport java.util.ArrayDeque;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.BlockingQueue;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.Callable;
227f4b6842ce2388b8e60cd31bdc3273f80472f632Gilles Debunneimport java.util.concurrent.CancellationException;
2381de61bfddceba0eb77b3aacea317594b0f1de49Joe Onoratoimport java.util.concurrent.Executor;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.ExecutionException;
257f4b6842ce2388b8e60cd31bdc3273f80472f632Gilles Debunneimport java.util.concurrent.FutureTask;
267f4b6842ce2388b8e60cd31bdc3273f80472f632Gilles Debunneimport java.util.concurrent.LinkedBlockingQueue;
277f4b6842ce2388b8e60cd31bdc3273f80472f632Gilles Debunneimport java.util.concurrent.ThreadFactory;
287f4b6842ce2388b8e60cd31bdc3273f80472f632Gilles Debunneimport java.util.concurrent.ThreadPoolExecutor;
297f4b6842ce2388b8e60cd31bdc3273f80472f632Gilles Debunneimport java.util.concurrent.TimeUnit;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.TimeoutException;
315ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guyimport java.util.concurrent.atomic.AtomicBoolean;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.atomic.AtomicInteger;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
350bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy * <p>AsyncTask enables proper and easy use of the UI thread. This class allows to
360bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy * perform background operations and publish results on the UI thread without
370bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy * having to manipulate threads and/or handlers.</p>
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
392c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * <p>AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler}
402c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * and does not constitute a generic threading framework. AsyncTasks should ideally be
412c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * used for short operations (a few seconds at the most.) If you need to keep threads
422c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * running for long periods of time, it is highly recommended you use the various APIs
432c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * provided by the <code>java.util.concurrent</code> pacakge such as {@link Executor},
442c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * {@link ThreadPoolExecutor} and {@link FutureTask}.</p>
452c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy *
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>An asynchronous task is defined by a computation that runs on a background thread and
470bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy * whose result is published on the UI thread. An asynchronous task is defined by 3 generic
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types, called <code>Params</code>, <code>Progress</code> and <code>Result</code>,
497f4b6842ce2388b8e60cd31bdc3273f80472f632Gilles Debunne * and 4 steps, called <code>onPreExecute</code>, <code>doInBackground</code>,
507f4b6842ce2388b8e60cd31bdc3273f80472f632Gilles Debunne * <code>onProgressUpdate</code> and <code>onPostExecute</code>.</p>
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
52b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * <div class="special reference">
53b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * <h3>Developer Guides</h3>
54b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * <p>For more information about using tasks and threads, read the
55b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
56b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * Threads</a> developer guide.</p>
57b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez * </div>
58b54e7a3d9f60ac605f404f9eb3c5e92ca51bbd23Joe Fernandez *
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h2>Usage</h2>
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>AsyncTask must be subclassed to be used. The subclass will override at least
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one method ({@link #doInBackground}), and most often will override a
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * second one ({@link #onPostExecute}.)</p>
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Here is an example of subclassing:</p>
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre class="prettyprint">
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * private class DownloadFilesTask extends AsyncTask&lt;URL, Integer, Long&gt; {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     protected Long doInBackground(URL... urls) {
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         int count = urls.length;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         long totalSize = 0;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         for (int i = 0; i < count; i++) {
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *             totalSize += Downloader.downloadFile(urls[i]);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *             publishProgress((int) ((i / (float) count) * 100));
732c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy *             // Escape early if cancel() is called
742c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy *             if (isCancelled()) break;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         }
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         return totalSize;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     protected void onProgressUpdate(Integer... progress) {
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         setProgressPercent(progress[0]);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     }
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     protected void onPostExecute(Long result) {
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         showDialog("Downloaded " + result + " bytes");
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     }
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * }
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre>
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Once created, a task is executed very simply:</p>
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre class="prettyprint">
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * new DownloadFilesTask().execute(url1, url2, url3);
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre>
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h2>AsyncTask's generic types</h2>
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The three types used by an asynchronous task are the following:</p>
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ol>
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li><code>Params</code>, the type of the parameters sent to the task upon
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     execution.</li>
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li><code>Progress</code>, the type of the progress units published during
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     the background computation.</li>
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li><code>Result</code>, the type of the result of the background
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     computation.</li>
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ol>
104202f560f85446008808e443ad28e438622bca49fOwen Lin * <p>Not all types are always used by an asynchronous task. To mark a type as unused,
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * simply use the type {@link Void}:</p>
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>
1076a1ae64f7735a3817713a223096bf8034f78a620Romain Guy * private class MyTask extends AsyncTask&lt;Void, Void, Void&gt; { ... }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre>
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h2>The 4 steps</h2>
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ol>
1136f931ccd31bc0a8a402072c1d87e682c8a30a404Romain Guy *     <li>{@link #onPreExecute()}, invoked on the UI thread before the task
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     is executed. This step is normally used to setup the task, for instance by
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     showing a progress bar in the user interface.</li>
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>{@link #doInBackground}, invoked on the background thread
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     immediately after {@link #onPreExecute()} finishes executing. This step is used
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     to perform background computation that can take a long time. The parameters
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     of the asynchronous task are passed to this step. The result of the computation must
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     be returned by this step and will be passed back to the last step. This step
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     can also use {@link #publishProgress} to publish one or more units
1220bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy *     of progress. These values are published on the UI thread, in the
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     {@link #onProgressUpdate} step.</li>
1240bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy *     <li>{@link #onProgressUpdate}, invoked on the UI thread after a
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     call to {@link #publishProgress}. The timing of the execution is
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     undefined. This method is used to display any form of progress in the user
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     interface while the background computation is still executing. For instance,
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     it can be used to animate a progress bar or show logs in a text field.</li>
1290bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy *     <li>{@link #onPostExecute}, invoked on the UI thread after the background
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     computation finishes. The result of the background computation is passed to
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     this step as a parameter.</li>
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ol>
133e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy *
134e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy * <h2>Cancelling a task</h2>
135e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy * <p>A task can be cancelled at any time by invoking {@link #cancel(boolean)}. Invoking
136e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy * this method will cause subsequent calls to {@link #isCancelled()} to return true.
1375ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy * After invoking this method, {@link #onCancelled(Object)}, instead of
1385ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy * {@link #onPostExecute(Object)} will be invoked after {@link #doInBackground(Object[])}
1395ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy * returns. To ensure that a task is cancelled as quickly as possible, you should always
1405ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy * check the return value of {@link #isCancelled()} periodically from
1415ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy * {@link #doInBackground(Object[])}, if possible (inside a loop for instance.)</p>
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h2>Threading rules</h2>
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>There are a few threading rules that must be followed for this class to
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work properly:</p>
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
1475e9120d4adfb07aeeadb0e0de1de2eb9ebbd80e0Romain Guy *     <li>The AsyncTask class must be loaded on the UI thread. This is done
1485e9120d4adfb07aeeadb0e0de1de2eb9ebbd80e0Romain Guy *     automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.</li>
1490bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy *     <li>The task instance must be created on the UI thread.</li>
1500bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy *     <li>{@link #execute} must be invoked on the UI thread.</li>
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>The task can be executed only once (an exception will be thrown if
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     a second execution is attempted.)</li>
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul>
156aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki *
157aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki * <h2>Memory observability</h2>
158aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki * <p>AsyncTask guarantees that all callback calls are synchronized in such a way that the following
159aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki * operations are safe without explicit synchronizations.</p>
160aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki * <ul>
161aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki *     <li>Set member fields in the constructor or {@link #onPreExecute}, and refer to them
162aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki *     in {@link #doInBackground}.
163aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki *     <li>Set member fields in {@link #doInBackground}, and refer to them in
164aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki *     {@link #onProgressUpdate} and {@link #onPostExecute}.
165aa60a02f7934ac23cb88f16ed2d726157bc9f31cMakoto Onuki * </ul>
1662c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy *
1672c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * <h2>Order of execution</h2>
1682c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * <p>When first introduced, AsyncTasks were executed serially on a single background
1692c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * thread. Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
1702c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * to a pool of threads allowing multiple tasks to operate in parallel. Starting with
1712c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are executed on a single
1722c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * thread to avoid common application errors caused by parallel execution.</p>
1732c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * <p>If you truly want parallel execution, you can invoke
1742c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * {@link #executeOnExecutor(java.util.concurrent.Executor, Object[])} with
1752c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy * {@link #THREAD_POOL_EXECUTOR}.</p>
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class AsyncTask<Params, Progress, Result> {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String LOG_TAG = "AsyncTask";
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
180719c44e03b97e850a46136ba336d729f5fbd1f47Romain Guy    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
181719c44e03b97e850a46136ba336d729f5fbd1f47Romain Guy    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
182719c44e03b97e850a46136ba336d729f5fbd1f47Romain Guy    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
1836b424f4770e1c4fe3e4c2a44d08447b0e9203dd4Romain Guy    private static final int KEEP_ALIVE = 1;
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final AtomicInteger mCount = new AtomicInteger(1);
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Thread newThread(Runnable r) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19381de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    private static final BlockingQueue<Runnable> sPoolWorkQueue =
194719c44e03b97e850a46136ba336d729f5fbd1f47Romain Guy            new LinkedBlockingQueue<Runnable>(128);
19581de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato
19681de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    /**
19796438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * An {@link Executor} that can be used to execute tasks in parallel.
19881de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     */
19996438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn    public static final Executor THREAD_POOL_EXECUTOR
20081de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
20181de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
20281de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato
20396438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn    /**
20496438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * An {@link Executor} that executes tasks one at a time in serial
20596438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * order.  This serialization is global to a particular process.
20696438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     */
20796438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn    public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int MESSAGE_POST_RESULT = 0x1;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int MESSAGE_POST_PROGRESS = 0x2;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2120bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy    private static final InternalHandler sHandler = new InternalHandler();
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
214d630f105e8bc0021541aacb4dc6498a49048eceaJoe Onorato    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final WorkerRunnable<Params, Result> mWorker;
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final FutureTask<Result> mFuture;
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private volatile Status mStatus = Status.PENDING;
2195ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy
220657f51371cc631a82a8d30cd4a796c48077d474bRomain Guy    private final AtomicBoolean mCancelled = new AtomicBoolean();
2215ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy    private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22381de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    private static class SerialExecutor implements Executor {
22481de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
22581de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato        Runnable mActive;
22681de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato
22781de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato        public synchronized void execute(final Runnable r) {
22881de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato            mTasks.offer(new Runnable() {
22981de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                public void run() {
23081de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                    try {
23181de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                        r.run();
23281de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                    } finally {
23381de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                        scheduleNext();
23481de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                    }
23581de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                }
23681de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato            });
23781de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato            if (mActive == null) {
23881de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                scheduleNext();
23981de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato            }
24081de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato        }
24181de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato
24281de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato        protected synchronized void scheduleNext() {
24381de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato            if ((mActive = mTasks.poll()) != null) {
24481de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato                THREAD_POOL_EXECUTOR.execute(mActive);
24581de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato            }
24681de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato        }
24781de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    }
24881de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates the current status of the task. Each status will be set only once
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * during the lifetime of a task.
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum Status {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Indicates that the task has not been executed yet.
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PENDING,
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Indicates that the task is running.
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RUNNING,
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Indicates that {@link AsyncTask#onPostExecute} has finished.
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FINISHED,
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2680bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy    /** @hide Used to force static handler to be created. */
26923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public static void init() {
2700bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy        sHandler.getLooper();
27123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
27223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
273d630f105e8bc0021541aacb4dc6498a49048eceaJoe Onorato    /** @hide */
274d630f105e8bc0021541aacb4dc6498a49048eceaJoe Onorato    public static void setDefaultExecutor(Executor exec) {
275d630f105e8bc0021541aacb4dc6498a49048eceaJoe Onorato        sDefaultExecutor = exec;
276d630f105e8bc0021541aacb4dc6498a49048eceaJoe Onorato    }
277d630f105e8bc0021541aacb4dc6498a49048eceaJoe Onorato
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2790bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AsyncTask() {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWorker = new WorkerRunnable<Params, Result>() {
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public Result call() throws Exception {
2845ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy                mTaskInvoked.set(true);
285e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy
2865ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
287657f51371cc631a82a8d30cd4a796c48077d474bRomain Guy                //noinspection unchecked
2885ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy                return postResult(doInBackground(mParams));
289bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov            }
290e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy        };
291bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov
292e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy        mFuture = new FutureTask<Result>(mWorker) {
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @Override
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            protected void done() {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
296657f51371cc631a82a8d30cd4a796c48077d474bRomain Guy                    postResultIfNotInvoked(get());
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (InterruptedException e) {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    android.util.Log.w(LOG_TAG, e);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (ExecutionException e) {
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException("An error occured while executing doInBackground()",
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            e.getCause());
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (CancellationException e) {
3035ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy                    postResultIfNotInvoked(null);
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        };
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3095ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy    private void postResultIfNotInvoked(Result result) {
3105ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy        final boolean wasTaskInvoked = mTaskInvoked.get();
3115ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy        if (!wasTaskInvoked) {
3125ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy            postResult(result);
3135ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy        }
3145ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy    }
3155ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy
3165ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy    private Result postResult(Result result) {
317657f51371cc631a82a8d30cd4a796c48077d474bRomain Guy        @SuppressWarnings("unchecked")
3185e7f2d0b227df38f6dbc2313ac8b5c9f225c135eRomain Guy        Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
3195ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy                new AsyncTaskResult<Result>(this, result));
3205ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy        message.sendToTarget();
3215ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy        return result;
3225ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy    }
3235ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the current status of this task.
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The current status.
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Status getStatus() {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mStatus;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this method to perform a computation on a background thread. The
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified parameters are the parameters passed to {@link #execute}
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the caller of this task.
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can call {@link #publishProgress} to publish updates
3390bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * on the UI thread.
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params The parameters of the task.
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return A result, defined by the subclass of this task.
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onPreExecute()
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onPostExecute
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #publishProgress
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected abstract Result doInBackground(Params... params);
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3520bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * Runs on the UI thread before {@link #doInBackground}.
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onPostExecute
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #doInBackground
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onPreExecute() {
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3610bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * <p>Runs on the UI thread after {@link #doInBackground}. The
362e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * specified result is the value returned by {@link #doInBackground}.</p>
363e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     *
364e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * <p>This method won't be invoked if the task was cancelled.</p>
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param result The result of the operation computed by {@link #doInBackground}.
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onPreExecute
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #doInBackground
3705ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * @see #onCancelled(Object)
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SuppressWarnings({"UnusedDeclaration"})
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onPostExecute(Result result) {
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3770bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * Runs on the UI thread after {@link #publishProgress} is invoked.
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The specified values are the values passed to {@link #publishProgress}.
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values The values indicating progress.
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #publishProgress
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #doInBackground
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SuppressWarnings({"UnusedDeclaration"})
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onProgressUpdate(Progress... values) {
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3900bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
3915ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * {@link #doInBackground(Object[])} has finished.</p>
3925ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     *
3935ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * <p>The default implementation simply invokes {@link #onCancelled()} and
3945ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * ignores the result. If you write your own implementation, do not call
3955ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * <code>super.onCancelled(result)</code>.</p>
3965ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     *
3975ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * @param result The result, if any, computed in
3985ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     *               {@link #doInBackground(Object[])}, can be null
3995ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     *
4005ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * @see #cancel(boolean)
4015ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * @see #isCancelled()
4025ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     */
4035ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy    @SuppressWarnings({"UnusedParameters"})
4045ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy    protected void onCancelled(Result result) {
4055ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy        onCancelled();
4065ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy    }
4075ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy
4085ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy    /**
4095ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * <p>Applications should preferably override {@link #onCancelled(Object)}.
4105ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * This method is invoked by the default implementation of
4115ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * {@link #onCancelled(Object)}.</p>
4125ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     *
4130bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
4145ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * {@link #doInBackground(Object[])} has finished.</p>
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4165ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * @see #onCancelled(Object)
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #cancel(boolean)
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isCancelled()
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onCancelled() {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns <tt>true</tt> if this task was cancelled before it completed
425e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * normally. If you are calling {@link #cancel(boolean)} on the task,
426e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * the value returned by this method should be checked periodically from
427e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * {@link #doInBackground(Object[])} to end the task as soon as possible.
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return <tt>true</tt> if task was cancelled before it completed
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #cancel(boolean)
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean isCancelled() {
434657f51371cc631a82a8d30cd4a796c48077d474bRomain Guy        return mCancelled.get();
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
438e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * <p>Attempts to cancel execution of this task.  This attempt will
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * fail if the task has already completed, already been cancelled,
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or could not be cancelled for some other reason. If successful,
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and this task has not started when <tt>cancel</tt> is called,
442e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * this task should never run. If the task has already started,
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * then the <tt>mayInterruptIfRunning</tt> parameter determines
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * whether the thread executing this task should be interrupted in
445e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * an attempt to stop the task.</p>
446e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     *
4475ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * <p>Calling this method will result in {@link #onCancelled(Object)} being
4480bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * invoked on the UI thread after {@link #doInBackground(Object[])}
449e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * returns. Calling this method guarantees that {@link #onPostExecute(Object)}
450e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * is never invoked. After invoking this method, you should check the
451e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * value returned by {@link #isCancelled()} periodically from
452e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * {@link #doInBackground(Object[])} to finish the task as early as
453e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy     * possible.</p>
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        task should be interrupted; otherwise, in-progress tasks are allowed
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        to complete.
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return <tt>false</tt> if the task could not be cancelled,
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         typically because it has already completed normally;
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         <tt>true</tt> otherwise
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isCancelled()
4645ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy     * @see #onCancelled(Object)
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean cancel(boolean mayInterruptIfRunning) {
467657f51371cc631a82a8d30cd4a796c48077d474bRomain Guy        mCancelled.set(true);
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFuture.cancel(mayInterruptIfRunning);
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Waits if necessary for the computation to complete, and then
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * retrieves its result.
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The computed result.
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws CancellationException If the computation was cancelled.
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws ExecutionException If the computation threw an exception.
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws InterruptedException If the current thread was interrupted
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         while waiting.
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Result get() throws InterruptedException, ExecutionException {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFuture.get();
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Waits if necessary for at most the given time for the computation
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to complete, and then retrieves its result.
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param timeout Time to wait before cancelling the operation.
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param unit The time unit for the timeout.
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The computed result.
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws CancellationException If the computation was cancelled.
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws ExecutionException If the computation threw an exception.
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws InterruptedException If the current thread was interrupted
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         while waiting.
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws TimeoutException If the wait timed out.
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ExecutionException, TimeoutException {
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFuture.get(timeout, unit);
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Executes the task with the specified parameters. The task returns
50896438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * itself (this) so that the caller can keep a reference to it.
50996438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     *
51096438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * <p>Note: this function schedules the task on a queue for a single background
51196438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * thread or pool of threads depending on the platform version.  When first
51296438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * introduced, AsyncTasks were executed serially on a single background thread.
51396438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
5142c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * to a pool of threads allowing multiple tasks to operate in parallel. Starting
5152c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are back to being
5162c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * executed on a single thread to avoid common application errors caused
51796438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * by parallel execution.  If you truly want parallel execution, you can use
51896438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * the {@link #executeOnExecutor} version of this method
5192c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings
5202c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * on its use.
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5220bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * <p>This method must be invoked on the UI thread.
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params The parameters of the task.
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return This instance of AsyncTask.
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalStateException If {@link #getStatus()} returns either
5290bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     *         {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
5302c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     *
5312c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
5322c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * @see #execute(Runnable)
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
535d630f105e8bc0021541aacb4dc6498a49048eceaJoe Onorato        return executeOnExecutor(sDefaultExecutor, params);
53681de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    }
53781de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato
53881de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    /**
53981de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     * Executes the task with the specified parameters. The task returns
54081de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     * itself (this) so that the caller can keep a reference to it.
54196438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     *
54296438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * <p>This method is typically used with {@link #THREAD_POOL_EXECUTOR} to
54396438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * allow multiple tasks to run in parallel on a pool of threads managed by
54496438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * AsyncTask, however you can also use your own {@link Executor} for custom
54596438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * behavior.
54696438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     *
54796438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * <p><em>Warning:</em> Allowing multiple tasks to run in parallel from
54896438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * a thread pool is generally <em>not</em> what one wants, because the order
54996438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * of their operation is not defined.  For example, if these tasks are used
55096438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * to modify any state in common (such as writing a file due to a button click),
55196438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * there are no guarantees on the order of the modifications.
55296438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * Without careful work it is possible in rare cases for the newer version
55396438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * of the data to be over-written by an older one, leading to obscure data
55496438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * loss and stability issues.  Such changes are best
55596438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * executed in serial; to guarantee such work is serialized regardless of
55696438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * platform version you can use this function with {@link #SERIAL_EXECUTOR}.
55781de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     *
5580bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * <p>This method must be invoked on the UI thread.
55981de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     *
56081de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     * @param exec The executor to use.  {@link #THREAD_POOL_EXECUTOR} is available as a
56181de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     *              convenient process-wide thread pool for tasks that are loosely coupled.
56281de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     * @param params The parameters of the task.
56381de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     *
56481de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     * @return This instance of AsyncTask.
56581de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     *
56681de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     * @throws IllegalStateException If {@link #getStatus()} returns either
5670bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     *         {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
5682c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     *
5692c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * @see #execute(Object[])
57081de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     */
57181de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
57281de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato            Params... params) {
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mStatus != Status.PENDING) {
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (mStatus) {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case RUNNING:
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalStateException("Cannot execute task:"
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + " the task is already running.");
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FINISHED:
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalStateException("Cannot execute task:"
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + " the task has already been executed "
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + "(a task can be executed only once)");
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatus = Status.RUNNING;
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onPreExecute();
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWorker.mParams = params;
59081de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato        exec.execute(mFuture);
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
59696438cd658f91fed9d8fc651c4eb1e55dc6dbf80Dianne Hackborn     * Convenience version of {@link #execute(Object...)} for use with
5972c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * a simple Runnable object. See {@link #execute(Object[])} for more
5982c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * information on the order of execution.
5992c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     *
6002c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * @see #execute(Object[])
6012c1b8c744daf1dfb3cc545effaf9a43e342a3d38Romain Guy     * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
60281de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato     */
60381de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    public static void execute(Runnable runnable) {
604d630f105e8bc0021541aacb4dc6498a49048eceaJoe Onorato        sDefaultExecutor.execute(runnable);
60581de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    }
60681de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato
60781de61bfddceba0eb77b3aacea317594b0f1de49Joe Onorato    /**
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be invoked from {@link #doInBackground} to
6090bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * publish updates on the UI thread while the background computation is
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * still running. Each call to this method will trigger the execution of
6110bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy     * {@link #onProgressUpdate} on the UI thread.
612bef9c7a59dc020c5cdcbd555b5212ae5a10e8045Dmitri Plotnikov     *
6134aaf8ec9dfb9a9e0f3d84e8ee95d7ac2ebca8d92Romain Guy     * {@link #onProgressUpdate} will note be called if the task has been
6144aaf8ec9dfb9a9e0f3d84e8ee95d7ac2ebca8d92Romain Guy     * canceled.
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values The progress values to update the UI with.
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onProgressUpdate
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #doInBackground
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void publishProgress(Progress... values) {
6224aaf8ec9dfb9a9e0f3d84e8ee95d7ac2ebca8d92Romain Guy        if (!isCancelled()) {
6230bbd8d8273c1dde9e0504f67bd8eb159bef2406aRomain Guy            sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
6244aaf8ec9dfb9a9e0f3d84e8ee95d7ac2ebca8d92Romain Guy                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();
6254aaf8ec9dfb9a9e0f3d84e8ee95d7ac2ebca8d92Romain Guy        }
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void finish(Result result) {
629e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy        if (isCancelled()) {
6305ba812b9e9c886425a5736c2ae6fbe0fc94afd8bRomain Guy            onCancelled(result);
631e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy        } else {
632e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy            onPostExecute(result);
633e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy        }
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatus = Status.FINISHED;
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class InternalHandler extends Handler {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void handleMessage(Message msg) {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (msg.what) {
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case MESSAGE_POST_RESULT:
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // There is only one result
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    result.mTask.finish(result.mData[0]);
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case MESSAGE_POST_PROGRESS:
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    result.mTask.onProgressUpdate(result.mData);
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Params[] mParams;
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SuppressWarnings({"RawUseOfParameterizedType"})
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class AsyncTaskResult<Data> {
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final AsyncTask mTask;
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Data[] mData;
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AsyncTaskResult(AsyncTask task, Data... data) {
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mTask = task;
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mData = data;
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
669