AsyncTask.java revision 202f560f85446008808e443ad28e438622bca49f
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
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.ThreadPoolExecutor;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.TimeUnit;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.BlockingQueue;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.LinkedBlockingQueue;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.ThreadFactory;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.Callable;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.FutureTask;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.ExecutionException;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.TimeoutException;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.CancellationException;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.atomic.AtomicInteger;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>AsyncTask enables proper and easy use of the UI thread. This class allows to
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * perform background operations and publish results on the UI thread without
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * having to manipulate threads and/or handlers.</p>
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>An asynchronous task is defined by a computation that runs on a background thread and
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * whose result is published on the UI thread. An asynchronous task is defined by 3 generic
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types, called <code>Params</code>, <code>Progress</code> and <code>Result</code>,
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and 4 steps, called <code>begin</code>, <code>doInBackground</code>,
40b97aec64be8a3f8c37b1735c981167b958d39403Romain Guy * <code>processProgress</code> and <code>end</code>.</p>
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h2>Usage</h2>
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>AsyncTask must be subclassed to be used. The subclass will override at least
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one method ({@link #doInBackground}), and most often will override a
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * second one ({@link #onPostExecute}.)</p>
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Here is an example of subclassing:</p>
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre class="prettyprint">
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * private class DownloadFilesTask extends AsyncTask&lt;URL, Integer, Long&gt; {
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     protected Long doInBackground(URL... urls) {
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         int count = urls.length;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         long totalSize = 0;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         for (int i = 0; i < count; i++) {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *             totalSize += Downloader.downloadFile(urls[i]);
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *             publishProgress((int) ((i / (float) count) * 100));
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         }
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         return totalSize;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     }
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     protected void onProgressUpdate(Integer... progress) {
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         setProgressPercent(progress[0]);
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     }
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     protected void onPostExecute(Long result) {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         showDialog("Downloaded " + result + " bytes");
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     }
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * }
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre>
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Once created, a task is executed very simply:</p>
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre class="prettyprint">
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * new DownloadFilesTask().execute(url1, url2, url3);
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre>
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h2>AsyncTask's generic types</h2>
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The three types used by an asynchronous task are the following:</p>
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ol>
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li><code>Params</code>, the type of the parameters sent to the task upon
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     execution.</li>
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li><code>Progress</code>, the type of the progress units published during
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     the background computation.</li>
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li><code>Result</code>, the type of the result of the background
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     computation.</li>
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ol>
85202f560f85446008808e443ad28e438622bca49fOwen Lin * <p>Not all types are always used by an asynchronous task. To mark a type as unused,
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * simply use the type {@link Void}:</p>
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>
886a1ae64f7735a3817713a223096bf8034f78a620Romain Guy * private class MyTask extends AsyncTask&lt;Void, Void, Void&gt; { ... }
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre>
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h2>The 4 steps</h2>
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ol>
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>{@link #onPreExecute()}, invoked on the UI thread immediately after the task
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     is executed. This step is normally used to setup the task, for instance by
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     showing a progress bar in the user interface.</li>
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>{@link #doInBackground}, invoked on the background thread
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     immediately after {@link #onPreExecute()} finishes executing. This step is used
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     to perform background computation that can take a long time. The parameters
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     of the asynchronous task are passed to this step. The result of the computation must
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     be returned by this step and will be passed back to the last step. This step
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     can also use {@link #publishProgress} to publish one or more units
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     of progress. These values are published on the UI thread, in the
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     {@link #onProgressUpdate} step.</li>
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>{@link #onProgressUpdate}, invoked on the UI thread after a
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     call to {@link #publishProgress}. The timing of the execution is
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     undefined. This method is used to display any form of progress in the user
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     interface while the background computation is still executing. For instance,
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     it can be used to animate a progress bar or show logs in a text field.</li>
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>{@link #onPostExecute}, invoked on the UI thread after the background
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     computation finishes. The result of the background computation is passed to
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     this step as a parameter.</li>
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ol>
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h2>Threading rules</h2>
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>There are a few threading rules that must be followed for this class to
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work properly:</p>
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>The task instance must be created on the UI thread.</li>
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>{@link #execute} must be invoked on the UI thread.</li>
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li>The task can be executed only once (an exception will be thrown if
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     a second execution is attempted.)</li>
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul>
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class AsyncTask<Params, Progress, Result> {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String LOG_TAG = "AsyncTask";
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
130a9be47cea45c19f2869732252e9922bf88fa4d86Romain Guy    private static final int CORE_POOL_SIZE = 5;
131a9be47cea45c19f2869732252e9922bf88fa4d86Romain Guy    private static final int MAXIMUM_POOL_SIZE = 128;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int KEEP_ALIVE = 10;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final BlockingQueue<Runnable> sWorkQueue =
135a9be47cea45c19f2869732252e9922bf88fa4d86Romain Guy            new LinkedBlockingQueue<Runnable>(10);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final AtomicInteger mCount = new AtomicInteger(1);
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Thread newThread(Runnable r) {
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int MESSAGE_POST_RESULT = 0x1;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int MESSAGE_POST_PROGRESS = 0x2;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int MESSAGE_POST_CANCEL = 0x3;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final InternalHandler sHandler = new InternalHandler();
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final WorkerRunnable<Params, Result> mWorker;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final FutureTask<Result> mFuture;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private volatile Status mStatus = Status.PENDING;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates the current status of the task. Each status will be set only once
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * during the lifetime of a task.
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum Status {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Indicates that the task has not been executed yet.
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PENDING,
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Indicates that the task is running.
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RUNNING,
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Indicates that {@link AsyncTask#onPostExecute} has finished.
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FINISHED,
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AsyncTask() {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWorker = new WorkerRunnable<Params, Result>() {
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public Result call() throws Exception {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return doInBackground(mParams);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        };
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFuture = new FutureTask<Result>(mWorker) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @Override
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            protected void done() {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Message message;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Result result = null;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    result = get();
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (InterruptedException e) {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    android.util.Log.w(LOG_TAG, e);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (ExecutionException e) {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException("An error occured while executing doInBackground()",
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            e.getCause());
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (CancellationException e) {
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    message.sendToTarget();
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (Throwable t) {
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new RuntimeException("An error occured while executing "
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + "doInBackground()", t);
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        new AsyncTaskResult<Result>(AsyncTask.this, result));
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                message.sendToTarget();
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        };
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the current status of this task.
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The current status.
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Status getStatus() {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mStatus;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this method to perform a computation on a background thread. The
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified parameters are the parameters passed to {@link #execute}
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the caller of this task.
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can call {@link #publishProgress} to publish updates
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * on the UI thread.
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params The parameters of the task.
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return A result, defined by the subclass of this task.
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onPreExecute()
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onPostExecute
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #publishProgress
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected abstract Result doInBackground(Params... params);
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs on the UI thread before {@link #doInBackground}.
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onPostExecute
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #doInBackground
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onPreExecute() {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs on the UI thread after {@link #doInBackground}. The
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified result is the value returned by {@link #doInBackground}
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or null if the task was cancelled or an exception occured.
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param result The result of the operation computed by {@link #doInBackground}.
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onPreExecute
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #doInBackground
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SuppressWarnings({"UnusedDeclaration"})
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onPostExecute(Result result) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs on the UI thread after {@link #publishProgress} is invoked.
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The specified values are the values passed to {@link #publishProgress}.
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values The values indicating progress.
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #publishProgress
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #doInBackground
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SuppressWarnings({"UnusedDeclaration"})
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onProgressUpdate(Progress... values) {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs on the UI thread after {@link #cancel(boolean)} is invoked.
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #cancel(boolean)
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isCancelled()
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onCancelled() {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns <tt>true</tt> if this task was cancelled before it completed
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * normally.
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return <tt>true</tt> if task was cancelled before it completed
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #cancel(boolean)
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean isCancelled() {
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFuture.isCancelled();
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Attempts to cancel execution of this task.  This attempt will
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * fail if the task has already completed, already been cancelled,
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or could not be cancelled for some other reason. If successful,
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and this task has not started when <tt>cancel</tt> is called,
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this task should never run.  If the task has already started,
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * then the <tt>mayInterruptIfRunning</tt> parameter determines
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * whether the thread executing this task should be interrupted in
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * an attempt to stop the task.
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        task should be interrupted; otherwise, in-progress tasks are allowed
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        to complete.
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return <tt>false</tt> if the task could not be cancelled,
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         typically because it has already completed normally;
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         <tt>true</tt> otherwise
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isCancelled()
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onCancelled()
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean cancel(boolean mayInterruptIfRunning) {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFuture.cancel(mayInterruptIfRunning);
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Waits if necessary for the computation to complete, and then
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * retrieves its result.
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The computed result.
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws CancellationException If the computation was cancelled.
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws ExecutionException If the computation threw an exception.
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws InterruptedException If the current thread was interrupted
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         while waiting.
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Result get() throws InterruptedException, ExecutionException {
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFuture.get();
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Waits if necessary for at most the given time for the computation
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to complete, and then retrieves its result.
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param timeout Time to wait before cancelling the operation.
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param unit The time unit for the timeout.
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The computed result.
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws CancellationException If the computation was cancelled.
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws ExecutionException If the computation threw an exception.
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws InterruptedException If the current thread was interrupted
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         while waiting.
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws TimeoutException If the wait timed out.
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ExecutionException, TimeoutException {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFuture.get(timeout, unit);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Executes the task with the specified parameters. The task returns
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * itself (this) so that the caller can keep a reference to it.
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method must be invoked on the UI thread.
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params The parameters of the task.
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return This instance of AsyncTask.
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalStateException If {@link #getStatus()} returns either
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mStatus != Status.PENDING) {
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (mStatus) {
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case RUNNING:
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalStateException("Cannot execute task:"
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + " the task is already running.");
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FINISHED:
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalStateException("Cannot execute task:"
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + " the task has already been executed "
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + "(a task can be executed only once)");
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatus = Status.RUNNING;
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onPreExecute();
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWorker.mParams = params;
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sExecutor.execute(mFuture);
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be invoked from {@link #doInBackground} to
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * publish updates on the UI thread while the background computation is
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * still running. Each call to this method will trigger the execution of
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onProgressUpdate} on the UI thread.
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values The progress values to update the UI with.
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #onProgressUpdate
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #doInBackground
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void publishProgress(Progress... values) {
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                new AsyncTaskResult<Progress>(this, values)).sendToTarget();
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void finish(Result result) {
4164b057801d5a5a859c2f9a68230744a6b0939ae01Romain Guy        if (isCancelled()) result = null;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onPostExecute(result);
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatus = Status.FINISHED;
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class InternalHandler extends Handler {
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void handleMessage(Message msg) {
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (msg.what) {
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case MESSAGE_POST_RESULT:
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // There is only one result
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    result.mTask.finish(result.mData[0]);
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case MESSAGE_POST_PROGRESS:
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    result.mTask.onProgressUpdate(result.mData);
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case MESSAGE_POST_CANCEL:
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    result.mTask.onCancelled();
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Params[] mParams;
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SuppressWarnings({"RawUseOfParameterizedType"})
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class AsyncTaskResult<Data> {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final AsyncTask mTask;
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Data[] mData;
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AsyncTaskResult(AsyncTask task, Data... data) {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mTask = task;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mData = data;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
456