Skip to content

Commit 0bbd8d8

Browse files
author
Romain Guy
committed
Revert "Check whether an AsyncTask is created/executed on a looper thread."
This reverts commit 7498ccb.
1 parent 5e7f2d0 commit 0bbd8d8

File tree

1 file changed

+28
-61
lines changed

1 file changed

+28
-61
lines changed

core/java/android/os/AsyncTask.java

Lines changed: 28 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,12 @@
3232
import 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>
@@ -102,7 +101,7 @@
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
@@ -111,14 +110,14 @@
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>
@@ -136,8 +135,8 @@
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
@@ -153,9 +152,6 @@
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
*/
160156
public 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-
>>>>>>> 6c0d0b8... 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

Comments
 (0)