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<URL, Integer, Long> { 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<Void, Void, Void> { ... } 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}