103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch/*
203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * Copyright (C) 2008 The Android Open Source Project
303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * Licensed under the Apache License, Version 2.0 (the "License");
503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * you may not use this file except in compliance with the License.
603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * You may obtain a copy of the License at
703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *      http://www.apache.org/licenses/LICENSE-2.0
903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
1003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * Unless required by applicable law or agreed to in writing, software
1103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * distributed under the License is distributed on an "AS IS" BASIS,
1203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * See the License for the specific language governing permissions and
1403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * limitations under the License.
1503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch */
1603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
1703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochpackage com.example.android.bitmapfun.util;
1803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
1903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport android.annotation.TargetApi;
2003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport android.os.Handler;
2103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport android.os.Message;
2203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport android.os.Process;
2303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
2403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.ArrayDeque;
2503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.BlockingQueue;
2603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.Callable;
2703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.CancellationException;
2803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.Executor;
2903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.ExecutionException;
3003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.Executors;
3103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.FutureTask;
3203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.LinkedBlockingQueue;
3303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.ThreadFactory;
3403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.ThreadPoolExecutor;
3503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.TimeUnit;
3603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.TimeoutException;
3703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.atomic.AtomicBoolean;
3803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.util.concurrent.atomic.AtomicInteger;
3903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
4003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch/**
4103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * *************************************
4203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * Copied from JB release framework:
4303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * https://android.googlesource.com/platform/frameworks/base/+/jb-release/core/java/android/os/AsyncTask.java
4403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
4503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * so that threading behavior on all OS versions is the same and we can tweak behavior by using
4603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * executeOnExecutor() if needed.
4703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
4803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * There are 3 changes in this copy of AsyncTask:
4903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *    -pre-HC a single thread executor is used for serial operation
5003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *    (Executors.newSingleThreadExecutor) and is the default
5103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *    -the default THREAD_POOL_EXECUTOR was changed to use DiscardOldestPolicy
5203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *    -a new fixed thread pool called DUAL_THREAD_EXECUTOR was added
5303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * *************************************
5403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
5503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>AsyncTask enables proper and easy use of the UI thread. This class allows to
5603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * perform background operations and publish results on the UI thread without
5703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * having to manipulate threads and/or handlers.</p>
5803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
5903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler}
6003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * and does not constitute a generic threading framework. AsyncTasks should ideally be
6103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * used for short operations (a few seconds at the most.) If you need to keep threads
6203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * running for long periods of time, it is highly recommended you use the various APIs
6303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * provided by the <code>java.util.concurrent</code> pacakge such as {@link Executor},
6403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * {@link ThreadPoolExecutor} and {@link FutureTask}.</p>
6503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
6603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>An asynchronous task is defined by a computation that runs on a background thread and
6703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * whose result is published on the UI thread. An asynchronous task is defined by 3 generic
6803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * types, called <code>Params</code>, <code>Progress</code> and <code>Result</code>,
6903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * and 4 steps, called <code>onPreExecute</code>, <code>doInBackground</code>,
7003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <code>onProgressUpdate</code> and <code>onPostExecute</code>.</p>
7103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
7203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <div class="special reference">
7303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <h3>Developer Guides</h3>
7403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>For more information about using tasks and threads, read the
7503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
7603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * Threads</a> developer guide.</p>
7703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * </div>
7803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
7903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <h2>Usage</h2>
8003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>AsyncTask must be subclassed to be used. The subclass will override at least
8103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * one method ({@link #doInBackground}), and most often will override a
8203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * second one ({@link #onPostExecute}.)</p>
8303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
8403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>Here is an example of subclassing:</p>
8503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <pre class="prettyprint">
8603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * private class DownloadFilesTask extends AsyncTask&lt;URL, Integer, Long&gt; {
8703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     protected Long doInBackground(URL... urls) {
8803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *         int count = urls.length;
8903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *         long totalSize = 0;
9003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *         for (int i = 0; i < count; i++) {
9103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *             totalSize += Downloader.downloadFile(urls[i]);
9203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *             publishProgress((int) ((i / (float) count) * 100));
9303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *             // Escape early if cancel() is called
9403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *             if (isCancelled()) break;
9503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *         }
9603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *         return totalSize;
9703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     }
9803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
9903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     protected void onProgressUpdate(Integer... progress) {
10003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *         setProgressPercent(progress[0]);
10103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     }
10203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
10303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     protected void onPostExecute(Long result) {
10403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *         showDialog("Downloaded " + result + " bytes");
10503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     }
10603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * }
10703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * </pre>
10803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
10903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>Once created, a task is executed very simply:</p>
11003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <pre class="prettyprint">
11103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * new DownloadFilesTask().execute(url1, url2, url3);
11203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * </pre>
11303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
11403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <h2>AsyncTask's generic types</h2>
11503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>The three types used by an asynchronous task are the following:</p>
11603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <ol>
11703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li><code>Params</code>, the type of the parameters sent to the task upon
11803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     execution.</li>
11903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li><code>Progress</code>, the type of the progress units published during
12003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     the background computation.</li>
12103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li><code>Result</code>, the type of the result of the background
12203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     computation.</li>
12303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * </ol>
12403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>Not all types are always used by an asynchronous task. To mark a type as unused,
12503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * simply use the type {@link Void}:</p>
12603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <pre>
12703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * private class MyTask extends AsyncTask&lt;Void, Void, Void&gt; { ... }
12803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * </pre>
12903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
13003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <h2>The 4 steps</h2>
13103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
13203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <ol>
13303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>{@link #onPreExecute()}, invoked on the UI thread immediately after the task
13403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     is executed. This step is normally used to setup the task, for instance by
13503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     showing a progress bar in the user interface.</li>
13603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>{@link #doInBackground}, invoked on the background thread
13703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     immediately after {@link #onPreExecute()} finishes executing. This step is used
13803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     to perform background computation that can take a long time. The parameters
13903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     of the asynchronous task are passed to this step. The result of the computation must
14003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     be returned by this step and will be passed back to the last step. This step
14103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     can also use {@link #publishProgress} to publish one or more units
14203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     of progress. These values are published on the UI thread, in the
14303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     {@link #onProgressUpdate} step.</li>
14403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>{@link #onProgressUpdate}, invoked on the UI thread after a
14503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     call to {@link #publishProgress}. The timing of the execution is
14603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     undefined. This method is used to display any form of progress in the user
14703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     interface while the background computation is still executing. For instance,
14803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     it can be used to animate a progress bar or show logs in a text field.</li>
14903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>{@link #onPostExecute}, invoked on the UI thread after the background
15003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     computation finishes. The result of the background computation is passed to
15103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     this step as a parameter.</li>
15203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * </ol>
15303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
15403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <h2>Cancelling a task</h2>
15503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>A task can be cancelled at any time by invoking {@link #cancel(boolean)}. Invoking
15603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * this method will cause subsequent calls to {@link #isCancelled()} to return true.
15703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * After invoking this method, {@link #onCancelled(Object)}, instead of
15803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * {@link #onPostExecute(Object)} will be invoked after {@link #doInBackground(Object[])}
15903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * returns. To ensure that a task is cancelled as quickly as possible, you should always
16003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * check the return value of {@link #isCancelled()} periodically from
16103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * {@link #doInBackground(Object[])}, if possible (inside a loop for instance.)</p>
16203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
16303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <h2>Threading rules</h2>
16403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>There are a few threading rules that must be followed for this class to
16503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * work properly:</p>
16603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <ul>
16703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>The AsyncTask class must be loaded on the UI thread. This is done
16803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.</li>
16903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>The task instance must be created on the UI thread.</li>
17003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>{@link #execute} must be invoked on the UI thread.</li>
17103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
17203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
17303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>The task can be executed only once (an exception will be thrown if
17403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     a second execution is attempted.)</li>
17503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * </ul>
17603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
17703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <h2>Memory observability</h2>
17803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>AsyncTask guarantees that all callback calls are synchronized in such a way that the following
17903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * operations are safe without explicit synchronizations.</p>
18003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <ul>
18103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>Set member fields in the constructor or {@link #onPreExecute}, and refer to them
18203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     in {@link #doInBackground}.
18303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     <li>Set member fields in {@link #doInBackground}, and refer to them in
18403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *     {@link #onProgressUpdate} and {@link #onPostExecute}.
18503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * </ul>
18603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch *
18703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <h2>Order of execution</h2>
18803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>When first introduced, AsyncTasks were executed serially on a single background
18903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * thread. Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
19003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * to a pool of threads allowing multiple tasks to operate in parallel. Starting with
19103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are executed on a single
19203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * thread to avoid common application errors caused by parallel execution.</p>
19303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * <p>If you truly want parallel execution, you can invoke
19403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * {@link #executeOnExecutor(java.util.concurrent.Executor, Object[])} with
19503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * {@link #THREAD_POOL_EXECUTOR}.</p>
19603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch */
19703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochpublic abstract class AsyncTask<Params, Progress, Result> {
19803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static final String LOG_TAG = "AsyncTask";
19903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
20003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static final int CORE_POOL_SIZE = 5;
20103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static final int MAXIMUM_POOL_SIZE = 128;
20203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static final int KEEP_ALIVE = 1;
20303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
20403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static final ThreadFactory  sThreadFactory = new ThreadFactory() {
20503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        private final AtomicInteger mCount = new AtomicInteger(1);
20603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
20703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        public Thread newThread(Runnable r) {
20803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
20903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        }
21003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    };
21103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
21203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static final BlockingQueue<Runnable> sPoolWorkQueue =
21303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            new LinkedBlockingQueue<Runnable>(10);
21403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
21503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
21603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * An {@link Executor} that can be used to execute tasks in parallel.
21703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
21803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public static final Executor THREAD_POOL_EXECUTOR
21903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
22003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory,
22103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            new ThreadPoolExecutor.DiscardOldestPolicy());
22203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
22303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
22403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * An {@link Executor} that executes tasks one at a time in serial
22503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * order.  This serialization is global to a particular process.
22603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
22703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public static final Executor SERIAL_EXECUTOR = Utils.hasHoneycomb() ? new SerialExecutor() :
22803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            Executors.newSingleThreadExecutor(sThreadFactory);
22903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
23003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public static final Executor DUAL_THREAD_EXECUTOR =
23103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            Executors.newFixedThreadPool(2, sThreadFactory);
23203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
23303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static final int MESSAGE_POST_RESULT = 0x1;
23403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static final int MESSAGE_POST_PROGRESS = 0x2;
23503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
23603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static final InternalHandler sHandler = new InternalHandler();
23703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
23803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
23903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private final WorkerRunnable<Params, Result> mWorker;
24003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private final FutureTask<Result> mFuture;
24103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
24203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private volatile Status mStatus = Status.PENDING;
24303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
24403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private final AtomicBoolean mCancelled = new AtomicBoolean();
24503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
24603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
24703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    @TargetApi(11)
24803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static class SerialExecutor implements Executor {
24903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
25003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        Runnable mActive;
25103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
25203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        public synchronized void execute(final Runnable r) {
25303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            mTasks.offer(new Runnable() {
25403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                public void run() {
25503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    try {
25603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                        r.run();
25703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    } finally {
25803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                        scheduleNext();
25903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    }
26003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                }
26103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            });
26203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            if (mActive == null) {
26303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                scheduleNext();
26403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            }
26503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        }
26603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
26703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        protected synchronized void scheduleNext() {
26803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            if ((mActive = mTasks.poll()) != null) {
26903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                THREAD_POOL_EXECUTOR.execute(mActive);
27003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            }
27103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        }
27203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
27303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
27403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
27503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Indicates the current status of the task. Each status will be set only once
27603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * during the lifetime of a task.
27703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
27803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public enum Status {
27903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        /**
28003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch         * Indicates that the task has not been executed yet.
28103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch         */
28203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        PENDING,
28303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        /**
28403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch         * Indicates that the task is running.
28503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch         */
28603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        RUNNING,
28703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        /**
28803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch         * Indicates that {@link AsyncTask#onPostExecute} has finished.
28903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch         */
29003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        FINISHED,
29103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
29203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
29303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /** @hide Used to force static handler to be created. */
29403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public static void init() {
29503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        sHandler.getLooper();
29603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
29703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
29803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /** @hide */
29903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public static void setDefaultExecutor(Executor exec) {
30003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        sDefaultExecutor = exec;
30103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
30203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
30303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
30403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
30503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
30603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public AsyncTask() {
30703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        mWorker = new WorkerRunnable<Params, Result>() {
30803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            public Result call() throws Exception {
30903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                mTaskInvoked.set(true);
31003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
31103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
31203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                //noinspection unchecked
31303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                return postResult(doInBackground(mParams));
31403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            }
31503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        };
31603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
31703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        mFuture = new FutureTask<Result>(mWorker) {
31803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            @Override
31903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            protected void done() {
32003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                try {
32103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    postResultIfNotInvoked(get());
32203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                } catch (InterruptedException e) {
32303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    android.util.Log.w(LOG_TAG, e);
32403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                } catch (ExecutionException e) {
32503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    throw new RuntimeException("An error occured while executing doInBackground()",
32603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                            e.getCause());
32703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                } catch (CancellationException e) {
32803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    postResultIfNotInvoked(null);
32903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                }
33003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            }
33103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        };
33203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
33303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
33403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private void postResultIfNotInvoked(Result result) {
33503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        final boolean wasTaskInvoked = mTaskInvoked.get();
33603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        if (!wasTaskInvoked) {
33703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            postResult(result);
33803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        }
33903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
34003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
34103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private Result postResult(Result result) {
34203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        @SuppressWarnings("unchecked")
34303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
34403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                new AsyncTaskResult<Result>(this, result));
34503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        message.sendToTarget();
34603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        return result;
34703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
34803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
34903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
35003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Returns the current status of this task.
35103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
35203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @return The current status.
35303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
35403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public final Status getStatus() {
35503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        return mStatus;
35603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
35703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
35803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
35903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Override this method to perform a computation on a background thread. The
36003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * specified parameters are the parameters passed to {@link #execute}
36103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * by the caller of this task.
36203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
36303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * This method can call {@link #publishProgress} to publish updates
36403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * on the UI thread.
36503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
36603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param params The parameters of the task.
36703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
36803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @return A result, defined by the subclass of this task.
36903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
37003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #onPreExecute()
37103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #onPostExecute
37203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #publishProgress
37303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
37403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    protected abstract Result doInBackground(Params... params);
37503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
37603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
37703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Runs on the UI thread before {@link #doInBackground}.
37803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
37903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #onPostExecute
38003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #doInBackground
38103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
38203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    protected void onPreExecute() {
38303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
38403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
38503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
38603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>Runs on the UI thread after {@link #doInBackground}. The
38703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * specified result is the value returned by {@link #doInBackground}.</p>
38803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
38903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>This method won't be invoked if the task was cancelled.</p>
39003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
39103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param result The result of the operation computed by {@link #doInBackground}.
39203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
39303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #onPreExecute
39403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #doInBackground
39503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #onCancelled(Object)
39603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
39703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    @SuppressWarnings({"UnusedDeclaration"})
39803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    protected void onPostExecute(Result result) {
39903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
40003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
40103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
40203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Runs on the UI thread after {@link #publishProgress} is invoked.
40303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * The specified values are the values passed to {@link #publishProgress}.
40403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
40503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param values The values indicating progress.
40603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
40703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #publishProgress
40803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #doInBackground
40903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
41003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    @SuppressWarnings({"UnusedDeclaration"})
41103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    protected void onProgressUpdate(Progress... values) {
41203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
41303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
41403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
41503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
41603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * {@link #doInBackground(Object[])} has finished.</p>
41703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
41803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>The default implementation simply invokes {@link #onCancelled()} and
41903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * ignores the result. If you write your own implementation, do not call
42003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <code>super.onCancelled(result)</code>.</p>
42103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
42203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param result The result, if any, computed in
42303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *               {@link #doInBackground(Object[])}, can be null
42403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
42503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #cancel(boolean)
42603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #isCancelled()
42703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
42803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    @SuppressWarnings({"UnusedParameters"})
42903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    protected void onCancelled(Result result) {
43003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        onCancelled();
43103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
43203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
43303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
43403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>Applications should preferably override {@link #onCancelled(Object)}.
43503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * This method is invoked by the default implementation of
43603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * {@link #onCancelled(Object)}.</p>
43703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
43803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
43903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * {@link #doInBackground(Object[])} has finished.</p>
44003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
44103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #onCancelled(Object)
44203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #cancel(boolean)
44303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #isCancelled()
44403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
44503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    protected void onCancelled() {
44603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
44703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
44803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
44903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Returns <tt>true</tt> if this task was cancelled before it completed
45003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * normally. If you are calling {@link #cancel(boolean)} on the task,
45103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * the value returned by this method should be checked periodically from
45203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * {@link #doInBackground(Object[])} to end the task as soon as possible.
45303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
45403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @return <tt>true</tt> if task was cancelled before it completed
45503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
45603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #cancel(boolean)
45703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
45803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public final boolean isCancelled() {
45903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        return mCancelled.get();
46003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
46103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
46203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
46303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>Attempts to cancel execution of this task.  This attempt will
46403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * fail if the task has already completed, already been cancelled,
46503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * or could not be cancelled for some other reason. If successful,
46603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * and this task has not started when <tt>cancel</tt> is called,
46703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * this task should never run. If the task has already started,
46803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * then the <tt>mayInterruptIfRunning</tt> parameter determines
46903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * whether the thread executing this task should be interrupted in
47003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * an attempt to stop the task.</p>
47103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
47203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>Calling this method will result in {@link #onCancelled(Object)} being
47303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * invoked on the UI thread after {@link #doInBackground(Object[])}
47403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * returns. Calling this method guarantees that {@link #onPostExecute(Object)}
47503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * is never invoked. After invoking this method, you should check the
47603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * value returned by {@link #isCancelled()} periodically from
47703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * {@link #doInBackground(Object[])} to finish the task as early as
47803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * possible.</p>
47903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
48003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
48103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *        task should be interrupted; otherwise, in-progress tasks are allowed
48203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *        to complete.
48303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
48403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @return <tt>false</tt> if the task could not be cancelled,
48503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *         typically because it has already completed normally;
48603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *         <tt>true</tt> otherwise
48703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
48803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #isCancelled()
48903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #onCancelled(Object)
49003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
49103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public final boolean cancel(boolean mayInterruptIfRunning) {
49203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        mCancelled.set(true);
49303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        return mFuture.cancel(mayInterruptIfRunning);
49403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
49503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
49603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
49703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Waits if necessary for the computation to complete, and then
49803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * retrieves its result.
49903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
50003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @return The computed result.
50103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
50203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @throws CancellationException If the computation was cancelled.
50303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @throws ExecutionException If the computation threw an exception.
50403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @throws InterruptedException If the current thread was interrupted
50503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *         while waiting.
50603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
50703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public final Result get() throws InterruptedException, ExecutionException {
50803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        return mFuture.get();
50903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
51003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
51103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
51203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Waits if necessary for at most the given time for the computation
51303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * to complete, and then retrieves its result.
51403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
51503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param timeout Time to wait before cancelling the operation.
51603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param unit The time unit for the timeout.
51703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
51803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @return The computed result.
51903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
52003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @throws CancellationException If the computation was cancelled.
52103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @throws ExecutionException If the computation threw an exception.
52203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @throws InterruptedException If the current thread was interrupted
52303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *         while waiting.
52403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @throws TimeoutException If the wait timed out.
52503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
52603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
52703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            ExecutionException, TimeoutException {
52803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        return mFuture.get(timeout, unit);
52903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
53003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
53103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
53203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Executes the task with the specified parameters. The task returns
53303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * itself (this) so that the caller can keep a reference to it.
53403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
53503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>Note: this function schedules the task on a queue for a single background
53603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * thread or pool of threads depending on the platform version.  When first
53703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * introduced, AsyncTasks were executed serially on a single background thread.
53803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
53903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * to a pool of threads allowing multiple tasks to operate in parallel. Starting
54003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are back to being
54103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * executed on a single thread to avoid common application errors caused
54203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * by parallel execution.  If you truly want parallel execution, you can use
54303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * the {@link #executeOnExecutor} version of this method
54403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings
54503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * on its use.
54603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
54703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>This method must be invoked on the UI thread.
54803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
54903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param params The parameters of the task.
55003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
55103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @return This instance of AsyncTask.
55203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
55303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @throws IllegalStateException If {@link #getStatus()} returns either
55403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *         {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
55503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
55603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
55703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #execute(Runnable)
55803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
55903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
56003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        return executeOnExecutor(sDefaultExecutor, params);
56103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
56203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
56303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
56403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Executes the task with the specified parameters. The task returns
56503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * itself (this) so that the caller can keep a reference to it.
56603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
56703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>This method is typically used with {@link #THREAD_POOL_EXECUTOR} to
56803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * allow multiple tasks to run in parallel on a pool of threads managed by
56903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * AsyncTask, however you can also use your own {@link Executor} for custom
57003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * behavior.
57103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
57203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p><em>Warning:</em> Allowing multiple tasks to run in parallel from
57303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * a thread pool is generally <em>not</em> what one wants, because the order
57403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * of their operation is not defined.  For example, if these tasks are used
57503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * to modify any state in common (such as writing a file due to a button click),
57603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * there are no guarantees on the order of the modifications.
57703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Without careful work it is possible in rare cases for the newer version
57803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * of the data to be over-written by an older one, leading to obscure data
57903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * loss and stability issues.  Such changes are best
58003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * executed in serial; to guarantee such work is serialized regardless of
58103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * platform version you can use this function with {@link #SERIAL_EXECUTOR}.
58203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
58303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * <p>This method must be invoked on the UI thread.
58403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
58503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param exec The executor to use.  {@link #THREAD_POOL_EXECUTOR} is available as a
58603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *              convenient process-wide thread pool for tasks that are loosely coupled.
58703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param params The parameters of the task.
58803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
58903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @return This instance of AsyncTask.
59003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
59103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @throws IllegalStateException If {@link #getStatus()} returns either
59203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *         {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
59303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
59403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #execute(Object[])
59503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
59603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
59703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            Params... params) {
59803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        if (mStatus != Status.PENDING) {
59903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            switch (mStatus) {
60003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                case RUNNING:
60103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    throw new IllegalStateException("Cannot execute task:"
60203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                            + " the task is already running.");
60303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                case FINISHED:
60403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    throw new IllegalStateException("Cannot execute task:"
60503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                            + " the task has already been executed "
60603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                            + "(a task can be executed only once)");
60703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            }
60803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        }
60903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
61003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        mStatus = Status.RUNNING;
61103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
61203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        onPreExecute();
61303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
61403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        mWorker.mParams = params;
61503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        exec.execute(mFuture);
61603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
61703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        return this;
61803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
61903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
62003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
62103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * Convenience version of {@link #execute(Object...)} for use with
62203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * a simple Runnable object. See {@link #execute(Object[])} for more
62303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * information on the order of execution.
62403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
62503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #execute(Object[])
62603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
62703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
62803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    public static void execute(Runnable runnable) {
62903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        sDefaultExecutor.execute(runnable);
63003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
63103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
63203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    /**
63303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * This method can be invoked from {@link #doInBackground} to
63403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * publish updates on the UI thread while the background computation is
63503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * still running. Each call to this method will trigger the execution of
63603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * {@link #onProgressUpdate} on the UI thread.
63703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
63803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * {@link #onProgressUpdate} will note be called if the task has been
63903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * canceled.
64003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
64103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @param values The progress values to update the UI with.
64203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     *
64303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #onProgressUpdate
64403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     * @see #doInBackground
64503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch     */
64603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    protected final void publishProgress(Progress... values) {
64703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        if (!isCancelled()) {
64803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
64903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();
65003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        }
65103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
65203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
65303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private void finish(Result result) {
65403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        if (isCancelled()) {
65503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            onCancelled(result);
65603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        } else {
65703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            onPostExecute(result);
65803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        }
65903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        mStatus = Status.FINISHED;
66003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
66103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
66203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static class InternalHandler extends Handler {
66303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
66403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        @Override
66503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        public void handleMessage(Message msg) {
66603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
66703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            switch (msg.what) {
66803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                case MESSAGE_POST_RESULT:
66903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    // There is only one result
67003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    result.mTask.finish(result.mData[0]);
67103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    break;
67203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                case MESSAGE_POST_PROGRESS:
67303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    result.mTask.onProgressUpdate(result.mData);
67403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch                    break;
67503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            }
67603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        }
67703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
67803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
67903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
68003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        Params[] mParams;
68103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
68203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
68303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    @SuppressWarnings({"RawUseOfParameterizedType"})
68403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    private static class AsyncTaskResult<Data> {
68503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        final AsyncTask mTask;
68603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        final Data[] mData;
68703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch
68803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        AsyncTaskResult(AsyncTask task, Data... data) {
68903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            mTask = task;
69003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch            mData = data;
69103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch        }
69203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch    }
69303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch}