3232import java .util .concurrent .atomic .AtomicInteger ;
3333
3434/**
35- * <p>AsyncTask enables proper and easy use of the UI thread (also called main thread) or
36- * any other looper thread. AsyncTask is most commonly used to interact with the UI thread.
37- * This class allows to perform background operations and publish results on a looper
38- * thread without having to manipulate threads and/or handlers.</p>
35+ * <p>AsyncTask enables proper and easy use of the UI thread. This class allows to
36+ * perform background operations and publish results on the UI thread without
37+ * having to manipulate threads and/or handlers.</p>
3938 *
4039 * <p>An asynchronous task is defined by a computation that runs on a background thread and
41- * whose result is published on a looper thread. An asynchronous task is defined by 3 generic
40+ * whose result is published on the UI thread. An asynchronous task is defined by 3 generic
4241 * types, called <code>Params</code>, <code>Progress</code> and <code>Result</code>,
4342 * and 4 steps, called <code>onPreExecute</code>, <code>doInBackground</code>,
4443 * <code>onProgressUpdate</code> and <code>onPostExecute</code>.</p>
102101 * <h2>The 4 steps</h2>
103102 * <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
104103 * <ol>
105- * <li>{@link #onPreExecute()}, invoked on the looper thread immediately after the task
104+ * <li>{@link #onPreExecute()}, invoked on the UI thread immediately after the task
106105 * is executed. This step is normally used to setup the task, for instance by
107106 * showing a progress bar in the user interface.</li>
108107 * <li>{@link #doInBackground}, invoked on the background thread
111110 * of the asynchronous task are passed to this step. The result of the computation must
112111 * be returned by this step and will be passed back to the last step. This step
113112 * can also use {@link #publishProgress} to publish one or more units
114- * of progress. These values are published on the looper thread, in the
113+ * of progress. These values are published on the UI thread, in the
115114 * {@link #onProgressUpdate} step.</li>
116- * <li>{@link #onProgressUpdate}, invoked on the looper thread after a
115+ * <li>{@link #onProgressUpdate}, invoked on the UI thread after a
117116 * call to {@link #publishProgress}. The timing of the execution is
118117 * undefined. This method is used to display any form of progress in the user
119118 * interface while the background computation is still executing. For instance,
120119 * it can be used to animate a progress bar or show logs in a text field.</li>
121- * <li>{@link #onPostExecute}, invoked on the looper thread after the background
120+ * <li>{@link #onPostExecute}, invoked on the UI thread after the background
122121 * computation finishes. The result of the background computation is passed to
123122 * this step as a parameter.</li>
124123 * </ol>
136135 * <p>There are a few threading rules that must be followed for this class to
137136 * work properly:</p>
138137 * <ul>
139- * <li>The task instance must be created on the looper thread.</li>
140- * <li>{@link #execute} must be invoked on the looper thread.</li>
138+ * <li>The task instance must be created on the UI thread.</li>
139+ * <li>{@link #execute} must be invoked on the UI thread.</li>
141140 * <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
142141 * {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
143142 * <li>The task can be executed only once (an exception will be thrown if
153152 * <li>Set member fields in {@link #doInBackground}, and refer to them in
154153 * {@link #onProgressUpdate} and {@link #onPostExecute}.
155154 * </ul>
156- *
157- * @see Looper
158- * @see Handler
159155 */
160156public abstract class AsyncTask <Params , Progress , Result > {
161157 private static final String LOG_TAG = "AsyncTask" ;
@@ -191,13 +187,7 @@ public Thread newThread(Runnable r) {
191187 private static final int MESSAGE_POST_RESULT = 0x1 ;
192188 private static final int MESSAGE_POST_PROGRESS = 0x2 ;
193189
194- private static final ThreadLocal <InternalHandler > sHandler =
195- new ThreadLocal <InternalHandler >() {
196- @ Override
197- protected InternalHandler initialValue () {
198- return new InternalHandler ();
199- }
200- };
190+ private static final InternalHandler sHandler = new InternalHandler ();
201191
202192 private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR ;
203193 private final WorkerRunnable <Params , Result > mWorker ;
@@ -206,7 +196,6 @@ protected InternalHandler initialValue() {
206196 private volatile Status mStatus = Status .PENDING ;
207197
208198 private final AtomicBoolean mTaskInvoked = new AtomicBoolean ();
209- private final InternalHandler mHandler ;
210199
211200 private static class SerialExecutor implements Executor {
212201 final ArrayDeque <Runnable > mTasks = new ArrayDeque <Runnable >();
@@ -253,8 +242,9 @@ public enum Status {
253242 FINISHED ,
254243 }
255244
256- /** @hide */
245+ /** @hide Used to force static handler to be created. */
257246 public static void init () {
247+ sHandler .getLooper ();
258248 }
259249
260250 /** @hide */
@@ -263,20 +253,9 @@ public static void setDefaultExecutor(Executor exec) {
263253 }
264254
265255 /**
266- * Creates a new asynchronous task. This constructor must be invoked on the looper thread.
267- *
268- * @throws IllegalStateException if this constructor is invoked on a non-looper thread
269- *
270- * @see Looper
256+ * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
271257 */
272258 public AsyncTask () {
273- if (Looper .myLooper () == null ) {
274- throw new IllegalStateException ("AsyncTask can be only instanciated on a "
275- + "looper thread. The current thread is " + Thread .currentThread ());
276- }
277-
278- mHandler = sHandler .get ();
279-
280259 mWorker = new WorkerRunnable <Params , Result >() {
281260 public Result call () throws Exception {
282261 mTaskInvoked .set (true );
@@ -316,12 +295,7 @@ private void postResultIfNotInvoked(Result result) {
316295 }
317296
318297 private Result postResult (Result result ) {
319- <<<<<<< HEAD
320298 Message message = sHandler .obtainMessage (MESSAGE_POST_RESULT ,
321- =======
322- @ SuppressWarnings ({"unchecked" })
323- Message message = mHandler .obtainMessage (MESSAGE_POST_RESULT ,
324- >>>>>>> 6 c0d0b8 ... Check whether an AsyncTask is created /executed on a looper thread .
325299 new AsyncTaskResult <Result >(this , result ));
326300 message .sendToTarget ();
327301 return result ;
@@ -342,7 +316,7 @@ public final Status getStatus() {
342316 * by the caller of this task.
343317 *
344318 * This method can call {@link #publishProgress} to publish updates
345- * on the looper thread.
319+ * on the UI thread.
346320 *
347321 * @param params The parameters of the task.
348322 *
@@ -355,7 +329,7 @@ public final Status getStatus() {
355329 protected abstract Result doInBackground (Params ... params );
356330
357331 /**
358- * Runs on the looper thread before {@link #doInBackground}.
332+ * Runs on the UI thread before {@link #doInBackground}.
359333 *
360334 * @see #onPostExecute
361335 * @see #doInBackground
@@ -364,7 +338,7 @@ protected void onPreExecute() {
364338 }
365339
366340 /**
367- * <p>Runs on the looper thread after {@link #doInBackground}. The
341+ * <p>Runs on the UI thread after {@link #doInBackground}. The
368342 * specified result is the value returned by {@link #doInBackground}.</p>
369343 *
370344 * <p>This method won't be invoked if the task was cancelled.</p>
@@ -380,7 +354,7 @@ protected void onPostExecute(Result result) {
380354 }
381355
382356 /**
383- * Runs on the looper thread after {@link #publishProgress} is invoked.
357+ * Runs on the UI thread after {@link #publishProgress} is invoked.
384358 * The specified values are the values passed to {@link #publishProgress}.
385359 *
386360 * @param values The values indicating progress.
@@ -393,7 +367,7 @@ protected void onProgressUpdate(Progress... values) {
393367 }
394368
395369 /**
396- * <p>Runs on the looper thread after {@link #cancel(boolean)} is invoked and
370+ * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
397371 * {@link #doInBackground(Object[])} has finished.</p>
398372 *
399373 * <p>The default implementation simply invokes {@link #onCancelled()} and
@@ -416,7 +390,7 @@ protected void onCancelled(Result result) {
416390 * This method is invoked by the default implementation of
417391 * {@link #onCancelled(Object)}.</p>
418392 *
419- * <p>Runs on the looper thread after {@link #cancel(boolean)} is invoked and
393+ * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
420394 * {@link #doInBackground(Object[])} has finished.</p>
421395 *
422396 * @see #onCancelled(Object)
@@ -451,7 +425,7 @@ public final boolean isCancelled() {
451425 * an attempt to stop the task.</p>
452426 *
453427 * <p>Calling this method will result in {@link #onCancelled(Object)} being
454- * invoked on the looper thread after {@link #doInBackground(Object[])}
428+ * invoked on the UI thread after {@link #doInBackground(Object[])}
455429 * returns. Calling this method guarantees that {@link #onPostExecute(Object)}
456430 * is never invoked. After invoking this method, you should check the
457431 * value returned by {@link #isCancelled()} periodically from
@@ -524,15 +498,14 @@ public final Result get(long timeout, TimeUnit unit) throws InterruptedException
524498 * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings on
525499 * its use.
526500 *
527- * <p>This method must be invoked on the looper thread.
501+ * <p>This method must be invoked on the UI thread.
528502 *
529503 * @param params The parameters of the task.
530504 *
531505 * @return This instance of AsyncTask.
532506 *
533507 * @throws IllegalStateException If {@link #getStatus()} returns either
534- * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED} or
535- * the current thread is not a looper thread.
508+ * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
536509 */
537510 public final AsyncTask <Params , Progress , Result > execute (Params ... params ) {
538511 return executeOnExecutor (sDefaultExecutor , params );
@@ -558,7 +531,7 @@ public final AsyncTask<Params, Progress, Result> execute(Params... params) {
558531 * executed in serial; to guarantee such work is serialized regardless of
559532 * platform version you can use this function with {@link #SERIAL_EXECUTOR}.
560533 *
561- * <p>This method must be invoked on the looper thread.
534+ * <p>This method must be invoked on the UI thread.
562535 *
563536 * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a
564537 * convenient process-wide thread pool for tasks that are loosely coupled.
@@ -567,16 +540,10 @@ public final AsyncTask<Params, Progress, Result> execute(Params... params) {
567540 * @return This instance of AsyncTask.
568541 *
569542 * @throws IllegalStateException If {@link #getStatus()} returns either
570- * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED} or
571- * the current thread is not a looper thread.
543+ * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
572544 */
573545 public final AsyncTask <Params , Progress , Result > executeOnExecutor (Executor exec ,
574546 Params ... params ) {
575- if (Looper .myLooper () == null ) {
576- throw new IllegalStateException ("AsyncTask can be only instanciated on a "
577- + "looper thread. The current thread is " + Thread .currentThread ());
578- }
579-
580547 if (mStatus != Status .PENDING ) {
581548 switch (mStatus ) {
582549 case RUNNING :
@@ -609,9 +576,9 @@ public static void execute(Runnable runnable) {
609576
610577 /**
611578 * This method can be invoked from {@link #doInBackground} to
612- * publish updates on the looper thread while the background computation is
579+ * publish updates on the UI thread while the background computation is
613580 * still running. Each call to this method will trigger the execution of
614- * {@link #onProgressUpdate} on the looper thread.
581+ * {@link #onProgressUpdate} on the UI thread.
615582 *
616583 * {@link #onProgressUpdate} will note be called if the task has been
617584 * canceled.
@@ -623,7 +590,7 @@ public static void execute(Runnable runnable) {
623590 */
624591 protected final void publishProgress (Progress ... values ) {
625592 if (!isCancelled ()) {
626- mHandler .obtainMessage (MESSAGE_POST_PROGRESS ,
593+ sHandler .obtainMessage (MESSAGE_POST_PROGRESS ,
627594 new AsyncTaskResult <Progress >(this , values )).sendToTarget ();
628595 }
629596 }
0 commit comments