blob: 928df3c4ff971e21a39b2d3577493ba866a2996e [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.os;
18
Eugene Suslaa38fbf62017-03-14 10:26:10 -070019import android.annotation.NonNull;
20import android.annotation.Nullable;
Andrei Onea24ec3212019-03-15 17:35:05 +000021import android.annotation.UnsupportedAppUsage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.util.Log;
23import android.util.Printer;
24
25import java.lang.reflect.Modifier;
26
27/**
28 * A Handler allows you to send and process {@link Message} and Runnable
29 * objects associated with a thread's {@link MessageQueue}. Each Handler
30 * instance is associated with a single thread and that thread's message
Charles Munger80b1c4d2019-11-12 09:00:48 -080031 * queue. When you create a new Handler it is bound to a {@link Looper}.
32 * It will deliver messages and runnables to that Looper's message
33 * queue and execute them on that Looper's thread.
34 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035 * <p>There are two main uses for a Handler: (1) to schedule messages and
kopriva9b5c0392018-09-10 14:02:58 -070036 * runnables to be executed at some point in the future; and (2) to enqueue
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037 * an action to be performed on a different thread than your own.
Charles Munger80b1c4d2019-11-12 09:00:48 -080038 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039 * <p>Scheduling messages is accomplished with the
40 * {@link #post}, {@link #postAtTime(Runnable, long)},
41 * {@link #postDelayed}, {@link #sendEmptyMessage},
42 * {@link #sendMessage}, {@link #sendMessageAtTime}, and
43 * {@link #sendMessageDelayed} methods. The <em>post</em> versions allow
44 * you to enqueue Runnable objects to be called by the message queue when
45 * they are received; the <em>sendMessage</em> versions allow you to enqueue
46 * a {@link Message} object containing a bundle of data that will be
47 * processed by the Handler's {@link #handleMessage} method (requiring that
48 * you implement a subclass of Handler).
49 *
50 * <p>When posting or sending to a Handler, you can either
51 * allow the item to be processed as soon as the message queue is ready
52 * to do so, or specify a delay before it gets processed or absolute time for
53 * it to be processed. The latter two allow you to implement timeouts,
54 * ticks, and other timing-based behavior.
55 *
56 * <p>When a
57 * process is created for your application, its main thread is dedicated to
58 * running a message queue that takes care of managing the top-level
59 * application objects (activities, broadcast receivers, etc) and any windows
60 * they create. You can create your own threads, and communicate back with
61 * the main application thread through a Handler. This is done by calling
62 * the same <em>post</em> or <em>sendMessage</em> methods as before, but from
Chris Palmer42855142010-09-09 17:04:31 -070063 * your new thread. The given Runnable or Message will then be scheduled
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 * in the Handler's message queue and processed when appropriate.
65 */
66public class Handler {
67 /*
68 * Set this flag to true to detect anonymous, local or member classes
69 * that extend this Handler class and that are not static. These kind
70 * of classes can potentially create leaks.
71 */
72 private static final boolean FIND_POTENTIAL_LEAKS = false;
73 private static final String TAG = "Handler";
Eugene Suslaa38fbf62017-03-14 10:26:10 -070074 private static Handler MAIN_THREAD_HANDLER = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075
76 /**
77 * Callback interface you can use when instantiating a Handler to avoid
78 * having to implement your own subclass of Handler.
79 */
80 public interface Callback {
Pavel Grafovdcc53572017-03-10 19:39:14 +000081 /**
82 * @param msg A {@link android.os.Message Message} object
83 * @return True if no further handling is desired
84 */
Jake Wharton720530b2019-03-08 12:05:53 -050085 boolean handleMessage(@NonNull Message msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 }
87
88 /**
89 * Subclasses must implement this to receive messages.
90 */
Jake Wharton720530b2019-03-08 12:05:53 -050091 public void handleMessage(@NonNull Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 }
93
94 /**
95 * Handle system messages here.
96 */
Jake Wharton720530b2019-03-08 12:05:53 -050097 public void dispatchMessage(@NonNull Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 if (msg.callback != null) {
99 handleCallback(msg);
100 } else {
101 if (mCallback != null) {
102 if (mCallback.handleMessage(msg)) {
103 return;
104 }
105 }
106 handleMessage(msg);
107 }
108 }
109
110 /**
Jeff Browna2910d02012-08-25 12:29:46 -0700111 * Default constructor associates this handler with the {@link Looper} for the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 * current thread.
113 *
Jeff Browna2910d02012-08-25 12:29:46 -0700114 * If this thread does not have a looper, this handler won't be able to receive messages
115 * so an exception is thrown.
Charles Munger80b1c4d2019-11-12 09:00:48 -0800116 *
117 * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
118 * where operations are silently lost (if the Handler is not expecting new tasks and quits),
119 * crashes (if a handler is sometimes created on a thread without a Looper active), or race
120 * conditions, where the thread a handler is associated with is not what the author
121 * anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper
122 * explicitly, using {@link Looper#getMainLooper}, {link android.view.View#getHandler}, or
123 * similar. If the implicit thread local behavior is required for compatibility, use
124 * {@code new Handler(Looper.myLooper())} to make it clear to readers.
125 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 */
Charles Munger80b1c4d2019-11-12 09:00:48 -0800127 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 public Handler() {
Jeff Browna2910d02012-08-25 12:29:46 -0700129 this(null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 }
131
132 /**
Jeff Browna2910d02012-08-25 12:29:46 -0700133 * Constructor associates this handler with the {@link Looper} for the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 * current thread and takes a callback interface in which you can handle
135 * messages.
Jeff Browna2910d02012-08-25 12:29:46 -0700136 *
137 * If this thread does not have a looper, this handler won't be able to receive messages
138 * so an exception is thrown.
139 *
140 * @param callback The callback interface in which to handle messages, or null.
Charles Munger80b1c4d2019-11-12 09:00:48 -0800141 *
142 * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
143 * where operations are silently lost (if the Handler is not expecting new tasks and quits),
144 * crashes (if a handler is sometimes created on a thread without a Looper active), or race
145 * conditions, where the thread a handler is associated with is not what the author
146 * anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper
147 * explicitly, using {@link Looper#getMainLooper}, {link android.view.View#getHandler}, or
148 * similar. If the implicit thread local behavior is required for compatibility, use
149 * {@code new Handler(Looper.myLooper(), callback)} to make it clear to readers.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 */
Charles Munger80b1c4d2019-11-12 09:00:48 -0800151 @Deprecated
Jake Wharton720530b2019-03-08 12:05:53 -0500152 public Handler(@Nullable Callback callback) {
Jeff Browna2910d02012-08-25 12:29:46 -0700153 this(callback, false);
154 }
155
156 /**
157 * Use the provided {@link Looper} instead of the default one.
158 *
159 * @param looper The looper, must not be null.
160 */
Jake Wharton720530b2019-03-08 12:05:53 -0500161 public Handler(@NonNull Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -0700162 this(looper, null, false);
163 }
164
165 /**
166 * Use the provided {@link Looper} instead of the default one and take a callback
167 * interface in which to handle messages.
168 *
169 * @param looper The looper, must not be null.
170 * @param callback The callback interface in which to handle messages, or null.
171 */
Jake Wharton720530b2019-03-08 12:05:53 -0500172 public Handler(@NonNull Looper looper, @Nullable Callback callback) {
Jeff Browna2910d02012-08-25 12:29:46 -0700173 this(looper, callback, false);
174 }
175
176 /**
177 * Use the {@link Looper} for the current thread
178 * and set whether the handler should be asynchronous.
179 *
180 * Handlers are synchronous by default unless this constructor is used to make
181 * one that is strictly asynchronous.
182 *
183 * Asynchronous messages represent interrupts or events that do not require global ordering
Jeff Brown9840c072014-11-11 20:21:21 -0800184 * with respect to synchronous messages. Asynchronous messages are not subject to
Jeff Browna2910d02012-08-25 12:29:46 -0700185 * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
186 *
187 * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
188 * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
189 *
190 * @hide
191 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000192 @UnsupportedAppUsage
Jeff Browna2910d02012-08-25 12:29:46 -0700193 public Handler(boolean async) {
194 this(null, async);
195 }
196
197 /**
198 * Use the {@link Looper} for the current thread with the specified callback interface
199 * and set whether the handler should be asynchronous.
200 *
201 * Handlers are synchronous by default unless this constructor is used to make
202 * one that is strictly asynchronous.
203 *
204 * Asynchronous messages represent interrupts or events that do not require global ordering
Jeff Brown9840c072014-11-11 20:21:21 -0800205 * with respect to synchronous messages. Asynchronous messages are not subject to
Jeff Browna2910d02012-08-25 12:29:46 -0700206 * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
207 *
208 * @param callback The callback interface in which to handle messages, or null.
209 * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
210 * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
211 *
212 * @hide
213 */
Jake Wharton720530b2019-03-08 12:05:53 -0500214 public Handler(@Nullable Callback callback, boolean async) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 if (FIND_POTENTIAL_LEAKS) {
216 final Class<? extends Handler> klass = getClass();
217 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
218 (klass.getModifiers() & Modifier.STATIC) == 0) {
219 Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
220 klass.getCanonicalName());
221 }
222 }
223
224 mLooper = Looper.myLooper();
225 if (mLooper == null) {
226 throw new RuntimeException(
Eugene Susla8f07ee12017-11-14 17:41:03 -0800227 "Can't create handler inside thread " + Thread.currentThread()
228 + " that has not called Looper.prepare()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 }
230 mQueue = mLooper.mQueue;
231 mCallback = callback;
Jeff Browna2910d02012-08-25 12:29:46 -0700232 mAsynchronous = async;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 }
234
235 /**
Jeff Browna2910d02012-08-25 12:29:46 -0700236 * Use the provided {@link Looper} instead of the default one and take a callback
Jeff Brown109025d2012-08-14 20:41:30 -0700237 * interface in which to handle messages. Also set whether the handler
238 * should be asynchronous.
239 *
240 * Handlers are synchronous by default unless this constructor is used to make
241 * one that is strictly asynchronous.
242 *
243 * Asynchronous messages represent interrupts or events that do not require global ordering
Jeff Brown9840c072014-11-11 20:21:21 -0800244 * with respect to synchronous messages. Asynchronous messages are not subject to
Adam Powell8709ba82018-02-21 10:18:25 -0800245 * the synchronization barriers introduced by conditions such as display vsync.
Jeff Brown109025d2012-08-14 20:41:30 -0700246 *
Jeff Browna2910d02012-08-25 12:29:46 -0700247 * @param looper The looper, must not be null.
248 * @param callback The callback interface in which to handle messages, or null.
Jeff Brown109025d2012-08-14 20:41:30 -0700249 * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
250 * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
251 *
252 * @hide
253 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000254 @UnsupportedAppUsage
Jake Wharton720530b2019-03-08 12:05:53 -0500255 public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
Jeff Brown109025d2012-08-14 20:41:30 -0700256 mLooper = looper;
257 mQueue = looper.mQueue;
258 mCallback = callback;
259 mAsynchronous = async;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 }
261
Adam Powell8709ba82018-02-21 10:18:25 -0800262 /**
263 * Create a new Handler whose posted messages and runnables are not subject to
264 * synchronization barriers such as display vsync.
265 *
266 * <p>Messages sent to an async handler are guaranteed to be ordered with respect to one another,
267 * but not necessarily with respect to messages from other Handlers.</p>
268 *
269 * @see #createAsync(Looper, Callback) to create an async Handler with custom message handling.
270 *
271 * @param looper the Looper that the new Handler should be bound to
272 * @return a new async Handler instance
273 */
274 @NonNull
275 public static Handler createAsync(@NonNull Looper looper) {
276 if (looper == null) throw new NullPointerException("looper must not be null");
277 return new Handler(looper, null, true);
278 }
279
280 /**
281 * Create a new Handler whose posted messages and runnables are not subject to
282 * synchronization barriers such as display vsync.
283 *
284 * <p>Messages sent to an async handler are guaranteed to be ordered with respect to one another,
285 * but not necessarily with respect to messages from other Handlers.</p>
286 *
287 * @see #createAsync(Looper) to create an async Handler without custom message handling.
288 *
289 * @param looper the Looper that the new Handler should be bound to
290 * @return a new async Handler instance
291 */
292 @NonNull
293 public static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) {
294 if (looper == null) throw new NullPointerException("looper must not be null");
295 if (callback == null) throw new NullPointerException("callback must not be null");
296 return new Handler(looper, callback, true);
297 }
298
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700299 /** @hide */
Andrei Onea24ec3212019-03-15 17:35:05 +0000300 @UnsupportedAppUsage
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700301 @NonNull
302 public static Handler getMain() {
303 if (MAIN_THREAD_HANDLER == null) {
304 MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper());
305 }
306 return MAIN_THREAD_HANDLER;
307 }
308
309 /** @hide */
310 @NonNull
311 public static Handler mainIfNull(@Nullable Handler handler) {
312 return handler == null ? getMain() : handler;
313 }
314
Jeff Sharkey74cd3de2016-04-06 17:40:54 -0600315 /** {@hide} */
Jake Wharton720530b2019-03-08 12:05:53 -0500316 @NonNull
317 public String getTraceName(@NonNull Message message) {
Felipe Leme4bc790d2019-09-16 17:52:07 -0700318 if (message.callback instanceof TraceNameSupplier) {
319 return ((TraceNameSupplier) message.callback).getTraceName();
320 }
321
Jeff Sharkey74cd3de2016-04-06 17:40:54 -0600322 final StringBuilder sb = new StringBuilder();
323 sb.append(getClass().getName()).append(": ");
324 if (message.callback != null) {
325 sb.append(message.callback.getClass().getName());
326 } else {
327 sb.append("#").append(message.what);
328 }
329 return sb.toString();
330 }
331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 /**
Romain Guyf9284692011-07-13 18:46:21 -0700333 * Returns a string representing the name of the specified message.
334 * The default implementation will either return the class name of the
335 * message callback if any, or the hexadecimal representation of the
336 * message "what" field.
337 *
338 * @param message The message whose name is being queried
339 */
Jake Wharton720530b2019-03-08 12:05:53 -0500340 @NonNull
341 public String getMessageName(@NonNull Message message) {
Romain Guyf9284692011-07-13 18:46:21 -0700342 if (message.callback != null) {
343 return message.callback.getClass().getName();
344 }
345 return "0x" + Integer.toHexString(message.what);
346 }
347
348 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
350 * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
351 * If you don't want that facility, just call Message.obtain() instead.
352 */
Jake Wharton720530b2019-03-08 12:05:53 -0500353 @NonNull
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 public final Message obtainMessage()
355 {
356 return Message.obtain(this);
357 }
358
359 /**
360 * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message.
361 *
362 * @param what Value to assign to the returned Message.what field.
363 * @return A Message from the global message pool.
364 */
Jake Wharton720530b2019-03-08 12:05:53 -0500365 @NonNull
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 public final Message obtainMessage(int what)
367 {
368 return Message.obtain(this, what);
369 }
370
371 /**
372 *
373 * Same as {@link #obtainMessage()}, except that it also sets the what and obj members
374 * of the returned Message.
375 *
376 * @param what Value to assign to the returned Message.what field.
377 * @param obj Value to assign to the returned Message.obj field.
378 * @return A Message from the global message pool.
379 */
Jake Wharton720530b2019-03-08 12:05:53 -0500380 @NonNull
381 public final Message obtainMessage(int what, @Nullable Object obj) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 return Message.obtain(this, what, obj);
383 }
384
385 /**
386 *
387 * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned
388 * Message.
389 * @param what Value to assign to the returned Message.what field.
390 * @param arg1 Value to assign to the returned Message.arg1 field.
391 * @param arg2 Value to assign to the returned Message.arg2 field.
392 * @return A Message from the global message pool.
393 */
Jake Wharton720530b2019-03-08 12:05:53 -0500394 @NonNull
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 public final Message obtainMessage(int what, int arg1, int arg2)
396 {
397 return Message.obtain(this, what, arg1, arg2);
398 }
399
400 /**
401 *
402 * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the
403 * returned Message.
404 * @param what Value to assign to the returned Message.what field.
405 * @param arg1 Value to assign to the returned Message.arg1 field.
406 * @param arg2 Value to assign to the returned Message.arg2 field.
407 * @param obj Value to assign to the returned Message.obj field.
408 * @return A Message from the global message pool.
409 */
Jake Wharton720530b2019-03-08 12:05:53 -0500410 @NonNull
411 public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 return Message.obtain(this, what, arg1, arg2, obj);
413 }
414
415 /**
416 * Causes the Runnable r to be added to the message queue.
417 * The runnable will be run on the thread to which this handler is
418 * attached.
419 *
420 * @param r The Runnable that will be executed.
421 *
422 * @return Returns true if the Runnable was successfully placed in to the
423 * message queue. Returns false on failure, usually because the
424 * looper processing the message queue is exiting.
425 */
Jake Wharton720530b2019-03-08 12:05:53 -0500426 public final boolean post(@NonNull Runnable r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 return sendMessageDelayed(getPostMessage(r), 0);
428 }
429
430 /**
431 * Causes the Runnable r to be added to the message queue, to be run
432 * at a specific time given by <var>uptimeMillis</var>.
433 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
David Christiea8cf4f22013-12-19 18:30:06 -0800434 * Time spent in deep sleep will add an additional delay to execution.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 * The runnable will be run on the thread to which this handler is attached.
436 *
437 * @param r The Runnable that will be executed.
438 * @param uptimeMillis The absolute time at which the callback should run,
439 * using the {@link android.os.SystemClock#uptimeMillis} time-base.
440 *
441 * @return Returns true if the Runnable was successfully placed in to the
442 * message queue. Returns false on failure, usually because the
443 * looper processing the message queue is exiting. Note that a
444 * result of true does not mean the Runnable will be processed -- if
445 * the looper is quit before the delivery time of the message
446 * occurs then the message will be dropped.
447 */
Jake Wharton720530b2019-03-08 12:05:53 -0500448 public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 return sendMessageAtTime(getPostMessage(r), uptimeMillis);
450 }
451
452 /**
453 * Causes the Runnable r to be added to the message queue, to be run
454 * at a specific time given by <var>uptimeMillis</var>.
455 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
David Christiea8cf4f22013-12-19 18:30:06 -0800456 * Time spent in deep sleep will add an additional delay to execution.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 * The runnable will be run on the thread to which this handler is attached.
458 *
459 * @param r The Runnable that will be executed.
Jake Wharton820e3dd2018-01-02 22:18:24 -0500460 * @param token An instance which can be used to cancel {@code r} via
461 * {@link #removeCallbacksAndMessages}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 * @param uptimeMillis The absolute time at which the callback should run,
463 * using the {@link android.os.SystemClock#uptimeMillis} time-base.
464 *
465 * @return Returns true if the Runnable was successfully placed in to the
466 * message queue. Returns false on failure, usually because the
467 * looper processing the message queue is exiting. Note that a
468 * result of true does not mean the Runnable will be processed -- if
469 * the looper is quit before the delivery time of the message
470 * occurs then the message will be dropped.
471 *
472 * @see android.os.SystemClock#uptimeMillis
473 */
Jake Wharton720530b2019-03-08 12:05:53 -0500474 public final boolean postAtTime(
475 @NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
477 }
478
479 /**
480 * Causes the Runnable r to be added to the message queue, to be run
481 * after the specified amount of time elapses.
482 * The runnable will be run on the thread to which this handler
483 * is attached.
David Christiea8cf4f22013-12-19 18:30:06 -0800484 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
485 * Time spent in deep sleep will add an additional delay to execution.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 *
487 * @param r The Runnable that will be executed.
488 * @param delayMillis The delay (in milliseconds) until the Runnable
489 * will be executed.
490 *
491 * @return Returns true if the Runnable was successfully placed in to the
492 * message queue. Returns false on failure, usually because the
493 * looper processing the message queue is exiting. Note that a
494 * result of true does not mean the Runnable will be processed --
495 * if the looper is quit before the delivery time of the message
496 * occurs then the message will be dropped.
497 */
Jake Wharton720530b2019-03-08 12:05:53 -0500498 public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 return sendMessageDelayed(getPostMessage(r), delayMillis);
500 }
501
Felipe Leme3fe6e922019-02-04 17:52:27 -0800502 /** @hide */
503 public final boolean postDelayed(Runnable r, int what, long delayMillis) {
504 return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
505 }
506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 /**
Jake Wharton820e3dd2018-01-02 22:18:24 -0500508 * Causes the Runnable r to be added to the message queue, to be run
509 * after the specified amount of time elapses.
510 * The runnable will be run on the thread to which this handler
511 * is attached.
512 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
513 * Time spent in deep sleep will add an additional delay to execution.
514 *
515 * @param r The Runnable that will be executed.
516 * @param token An instance which can be used to cancel {@code r} via
517 * {@link #removeCallbacksAndMessages}.
518 * @param delayMillis The delay (in milliseconds) until the Runnable
519 * will be executed.
520 *
521 * @return Returns true if the Runnable was successfully placed in to the
522 * message queue. Returns false on failure, usually because the
523 * looper processing the message queue is exiting. Note that a
524 * result of true does not mean the Runnable will be processed --
525 * if the looper is quit before the delivery time of the message
526 * occurs then the message will be dropped.
527 */
Jake Wharton720530b2019-03-08 12:05:53 -0500528 public final boolean postDelayed(
529 @NonNull Runnable r, @Nullable Object token, long delayMillis) {
Jake Wharton820e3dd2018-01-02 22:18:24 -0500530 return sendMessageDelayed(getPostMessage(r, token), delayMillis);
531 }
532
533 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 * Posts a message to an object that implements Runnable.
535 * Causes the Runnable r to executed on the next iteration through the
536 * message queue. The runnable will be run on the thread to which this
537 * handler is attached.
538 * <b>This method is only for use in very special circumstances -- it
539 * can easily starve the message queue, cause ordering problems, or have
540 * other unexpected side-effects.</b>
541 *
542 * @param r The Runnable that will be executed.
543 *
544 * @return Returns true if the message was successfully placed in to the
545 * message queue. Returns false on failure, usually because the
546 * looper processing the message queue is exiting.
547 */
Jake Wharton720530b2019-03-08 12:05:53 -0500548 public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 return sendMessageAtFrontOfQueue(getPostMessage(r));
550 }
551
552 /**
Jeff Brownc53abc42012-08-29 04:43:25 -0700553 * Runs the specified task synchronously.
Jeff Brown8b60e452013-04-18 15:17:48 -0700554 * <p>
Jeff Brownc53abc42012-08-29 04:43:25 -0700555 * If the current thread is the same as the handler thread, then the runnable
556 * runs immediately without being enqueued. Otherwise, posts the runnable
557 * to the handler and waits for it to complete before returning.
Jeff Brown8b60e452013-04-18 15:17:48 -0700558 * </p><p>
Jeff Brownc53abc42012-08-29 04:43:25 -0700559 * This method is dangerous! Improper use can result in deadlocks.
560 * Never call this method while any locks are held or use it in a
561 * possibly re-entrant manner.
Jeff Brown8b60e452013-04-18 15:17:48 -0700562 * </p><p>
Jeff Brownc53abc42012-08-29 04:43:25 -0700563 * This method is occasionally useful in situations where a background thread
564 * must synchronously await completion of a task that must run on the
565 * handler's thread. However, this problem is often a symptom of bad design.
566 * Consider improving the design (if possible) before resorting to this method.
Jeff Brown8b60e452013-04-18 15:17:48 -0700567 * </p><p>
Jeff Brownc53abc42012-08-29 04:43:25 -0700568 * One example of where you might want to use this method is when you just
569 * set up a Handler thread and need to perform some initialization steps on
570 * it before continuing execution.
Jeff Brown8b60e452013-04-18 15:17:48 -0700571 * </p><p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700572 * If timeout occurs then this method returns <code>false</code> but the runnable
573 * will remain posted on the handler and may already be in progress or
574 * complete at a later time.
Jeff Brown8b60e452013-04-18 15:17:48 -0700575 * </p><p>
576 * When using this method, be sure to use {@link Looper#quitSafely} when
577 * quitting the looper. Otherwise {@link #runWithScissors} may hang indefinitely.
578 * (TODO: We should fix this by making MessageQueue aware of blocking runnables.)
579 * </p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700580 *
Jeff Brownc53abc42012-08-29 04:43:25 -0700581 * @param r The Runnable that will be executed synchronously.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700582 * @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
Jeff Brownc53abc42012-08-29 04:43:25 -0700583 *
584 * @return Returns true if the Runnable was successfully executed.
585 * Returns false on failure, usually because the
586 * looper processing the message queue is exiting.
587 *
588 * @hide This method is prone to abuse and should probably not be in the API.
589 * If we ever do make it part of the API, we might want to rename it to something
590 * less funny like runUnsafe().
591 */
Jake Wharton720530b2019-03-08 12:05:53 -0500592 public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
Jeff Brownc53abc42012-08-29 04:43:25 -0700593 if (r == null) {
594 throw new IllegalArgumentException("runnable must not be null");
595 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700596 if (timeout < 0) {
597 throw new IllegalArgumentException("timeout must be non-negative");
598 }
Jeff Brownc53abc42012-08-29 04:43:25 -0700599
600 if (Looper.myLooper() == mLooper) {
601 r.run();
602 return true;
603 }
604
605 BlockingRunnable br = new BlockingRunnable(r);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700606 return br.postAndWait(this, timeout);
Jeff Brownc53abc42012-08-29 04:43:25 -0700607 }
608
609 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 * Remove any pending posts of Runnable r that are in the message queue.
611 */
Jake Wharton720530b2019-03-08 12:05:53 -0500612 public final void removeCallbacks(@NonNull Runnable r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 mQueue.removeMessages(this, r, null);
614 }
615
616 /**
617 * Remove any pending posts of Runnable <var>r</var> with Object
Dianne Hackborn466ed242011-07-21 18:16:31 -0700618 * <var>token</var> that are in the message queue. If <var>token</var> is null,
619 * all callbacks will be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800620 */
Jake Wharton720530b2019-03-08 12:05:53 -0500621 public final void removeCallbacks(@NonNull Runnable r, @Nullable Object token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 mQueue.removeMessages(this, r, token);
623 }
624
625 /**
626 * Pushes a message onto the end of the message queue after all pending messages
627 * before the current time. It will be received in {@link #handleMessage},
628 * in the thread attached to this handler.
629 *
630 * @return Returns true if the message was successfully placed in to the
631 * message queue. Returns false on failure, usually because the
632 * looper processing the message queue is exiting.
633 */
Jake Wharton720530b2019-03-08 12:05:53 -0500634 public final boolean sendMessage(@NonNull Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 return sendMessageDelayed(msg, 0);
636 }
637
638 /**
639 * Sends a Message containing only the what value.
640 *
641 * @return Returns true if the message was successfully placed in to the
642 * message queue. Returns false on failure, usually because the
643 * looper processing the message queue is exiting.
644 */
645 public final boolean sendEmptyMessage(int what)
646 {
647 return sendEmptyMessageDelayed(what, 0);
648 }
649
650 /**
651 * Sends a Message containing only the what value, to be delivered
652 * after the specified amount of time elapses.
653 * @see #sendMessageDelayed(android.os.Message, long)
654 *
655 * @return Returns true if the message was successfully placed in to the
656 * message queue. Returns false on failure, usually because the
657 * looper processing the message queue is exiting.
658 */
659 public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
660 Message msg = Message.obtain();
661 msg.what = what;
662 return sendMessageDelayed(msg, delayMillis);
663 }
664
665 /**
666 * Sends a Message containing only the what value, to be delivered
667 * at a specific time.
668 * @see #sendMessageAtTime(android.os.Message, long)
669 *
670 * @return Returns true if the message was successfully placed in to the
671 * message queue. Returns false on failure, usually because the
672 * looper processing the message queue is exiting.
673 */
674
675 public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
676 Message msg = Message.obtain();
677 msg.what = what;
678 return sendMessageAtTime(msg, uptimeMillis);
679 }
680
681 /**
682 * Enqueue a message into the message queue after all pending messages
683 * before (current time + delayMillis). You will receive it in
684 * {@link #handleMessage}, in the thread attached to this handler.
685 *
686 * @return Returns true if the message was successfully placed in to the
687 * message queue. Returns false on failure, usually because the
688 * looper processing the message queue is exiting. Note that a
689 * result of true does not mean the message will be processed -- if
690 * the looper is quit before the delivery time of the message
691 * occurs then the message will be dropped.
692 */
Jake Wharton720530b2019-03-08 12:05:53 -0500693 public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 if (delayMillis < 0) {
695 delayMillis = 0;
696 }
697 return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
698 }
699
700 /**
701 * Enqueue a message into the message queue after all pending messages
702 * before the absolute time (in milliseconds) <var>uptimeMillis</var>.
703 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
David Christiea8cf4f22013-12-19 18:30:06 -0800704 * Time spent in deep sleep will add an additional delay to execution.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800705 * You will receive it in {@link #handleMessage}, in the thread attached
706 * to this handler.
707 *
708 * @param uptimeMillis The absolute time at which the message should be
709 * delivered, using the
710 * {@link android.os.SystemClock#uptimeMillis} time-base.
711 *
712 * @return Returns true if the message was successfully placed in to the
713 * message queue. Returns false on failure, usually because the
714 * looper processing the message queue is exiting. Note that a
715 * result of true does not mean the message will be processed -- if
716 * the looper is quit before the delivery time of the message
717 * occurs then the message will be dropped.
718 */
Jake Wharton720530b2019-03-08 12:05:53 -0500719 public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 MessageQueue queue = mQueue;
Jeff Brown109025d2012-08-14 20:41:30 -0700721 if (queue == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 RuntimeException e = new RuntimeException(
Jeff Brown109025d2012-08-14 20:41:30 -0700723 this + " sendMessageAtTime() called with no mQueue");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800724 Log.w("Looper", e.getMessage(), e);
Jeff Brown109025d2012-08-14 20:41:30 -0700725 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800726 }
Jeff Brown109025d2012-08-14 20:41:30 -0700727 return enqueueMessage(queue, msg, uptimeMillis);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728 }
729
730 /**
731 * Enqueue a message at the front of the message queue, to be processed on
732 * the next iteration of the message loop. You will receive it in
733 * {@link #handleMessage}, in the thread attached to this handler.
734 * <b>This method is only for use in very special circumstances -- it
735 * can easily starve the message queue, cause ordering problems, or have
736 * other unexpected side-effects.</b>
737 *
738 * @return Returns true if the message was successfully placed in to the
739 * message queue. Returns false on failure, usually because the
740 * looper processing the message queue is exiting.
741 */
Jake Wharton720530b2019-03-08 12:05:53 -0500742 public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 MessageQueue queue = mQueue;
Jeff Brown109025d2012-08-14 20:41:30 -0700744 if (queue == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800745 RuntimeException e = new RuntimeException(
746 this + " sendMessageAtTime() called with no mQueue");
747 Log.w("Looper", e.getMessage(), e);
Jeff Brown109025d2012-08-14 20:41:30 -0700748 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749 }
Jeff Brown109025d2012-08-14 20:41:30 -0700750 return enqueueMessage(queue, msg, 0);
751 }
752
Eugene Susla9f35ca92018-02-12 16:17:26 -0800753 /**
754 * Executes the message synchronously if called on the same thread this handler corresponds to,
755 * or {@link #sendMessage pushes it to the queue} otherwise
756 *
757 * @return Returns true if the message was successfully ran or placed in to the
758 * message queue. Returns false on failure, usually because the
759 * looper processing the message queue is exiting.
760 * @hide
761 */
Jake Wharton720530b2019-03-08 12:05:53 -0500762 public final boolean executeOrSendMessage(@NonNull Message msg) {
Eugene Susla9f35ca92018-02-12 16:17:26 -0800763 if (mLooper == Looper.myLooper()) {
764 dispatchMessage(msg);
765 return true;
766 }
767 return sendMessage(msg);
768 }
769
Jake Wharton720530b2019-03-08 12:05:53 -0500770 private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
771 long uptimeMillis) {
Jeff Brown109025d2012-08-14 20:41:30 -0700772 msg.target = this;
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000773 msg.workSourceUid = ThreadLocalWorkSource.getUid();
Marcin Oczeretkoec758722018-09-12 12:53:47 +0100774
Jeff Brown109025d2012-08-14 20:41:30 -0700775 if (mAsynchronous) {
776 msg.setAsynchronous(true);
777 }
778 return queue.enqueueMessage(msg, uptimeMillis);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 }
780
781 /**
782 * Remove any pending posts of messages with code 'what' that are in the
783 * message queue.
784 */
785 public final void removeMessages(int what) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800786 mQueue.removeMessages(this, what, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 }
788
789 /**
790 * Remove any pending posts of messages with code 'what' and whose obj is
Jeff Brown32c81132012-04-30 16:28:32 -0700791 * 'object' that are in the message queue. If <var>object</var> is null,
Dianne Hackborn466ed242011-07-21 18:16:31 -0700792 * all messages will be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 */
Jake Wharton720530b2019-03-08 12:05:53 -0500794 public final void removeMessages(int what, @Nullable Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800795 mQueue.removeMessages(this, what, object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 }
797
798 /**
799 * Remove any pending posts of callbacks and sent messages whose
Dianne Hackborn466ed242011-07-21 18:16:31 -0700800 * <var>obj</var> is <var>token</var>. If <var>token</var> is null,
801 * all callbacks and messages will be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 */
Jake Wharton720530b2019-03-08 12:05:53 -0500803 public final void removeCallbacksAndMessages(@Nullable Object token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 mQueue.removeCallbacksAndMessages(this, token);
805 }
806
807 /**
808 * Check if there are any pending posts of messages with code 'what' in
809 * the message queue.
810 */
811 public final boolean hasMessages(int what) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800812 return mQueue.hasMessages(this, what, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 }
814
815 /**
Dianne Hackborncb015632017-06-14 17:30:15 -0700816 * Return whether there are any messages or callbacks currently scheduled on this handler.
817 * @hide
818 */
819 public final boolean hasMessagesOrCallbacks() {
820 return mQueue.hasMessages(this);
821 }
822
823 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 * Check if there are any pending posts of messages with code 'what' and
825 * whose obj is 'object' in the message queue.
826 */
Jake Wharton720530b2019-03-08 12:05:53 -0500827 public final boolean hasMessages(int what, @Nullable Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800828 return mQueue.hasMessages(this, what, object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 }
830
Romain Guyba6be8a2012-04-23 18:22:09 -0700831 /**
832 * Check if there are any pending posts of messages with callback r in
833 * the message queue.
Romain Guyba6be8a2012-04-23 18:22:09 -0700834 */
Jake Wharton720530b2019-03-08 12:05:53 -0500835 public final boolean hasCallbacks(@NonNull Runnable r) {
Romain Guyba6be8a2012-04-23 18:22:09 -0700836 return mQueue.hasMessages(this, r, null);
837 }
838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 // if we can get rid of this method, the handler need not remember its loop
840 // we could instead export a getMessageQueue() method...
Jake Wharton720530b2019-03-08 12:05:53 -0500841 @NonNull
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 public final Looper getLooper() {
843 return mLooper;
844 }
845
Jake Wharton720530b2019-03-08 12:05:53 -0500846 public final void dump(@NonNull Printer pw, @NonNull String prefix) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
848 if (mLooper == null) {
849 pw.println(prefix + "looper uninitialized");
850 } else {
851 mLooper.dump(pw, prefix + " ");
852 }
853 }
854
Dianne Hackborncb015632017-06-14 17:30:15 -0700855 /**
856 * @hide
857 */
Jake Wharton720530b2019-03-08 12:05:53 -0500858 public final void dumpMine(@NonNull Printer pw, @NonNull String prefix) {
Dianne Hackborncb015632017-06-14 17:30:15 -0700859 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
860 if (mLooper == null) {
861 pw.println(prefix + "looper uninitialized");
862 } else {
863 mLooper.dump(pw, prefix + " ", this);
864 }
865 }
866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 @Override
868 public String toString() {
Kristian Monsen588d8562011-08-04 12:55:33 +0100869 return "Handler (" + getClass().getName() + ") {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 + Integer.toHexString(System.identityHashCode(this))
871 + "}";
872 }
873
Andrei Onea24ec3212019-03-15 17:35:05 +0000874 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 final IMessenger getIMessenger() {
876 synchronized (mQueue) {
877 if (mMessenger != null) {
878 return mMessenger;
879 }
880 mMessenger = new MessengerImpl();
881 return mMessenger;
882 }
883 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 private final class MessengerImpl extends IMessenger.Stub {
886 public void send(Message msg) {
Dianne Hackborncb3ed1d2014-06-27 18:37:06 -0700887 msg.sendingUid = Binder.getCallingUid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888 Handler.this.sendMessage(msg);
889 }
890 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700891
Romain Guyba6be8a2012-04-23 18:22:09 -0700892 private static Message getPostMessage(Runnable r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 Message m = Message.obtain();
894 m.callback = r;
895 return m;
896 }
897
Andrei Onea24ec3212019-03-15 17:35:05 +0000898 @UnsupportedAppUsage
Romain Guyba6be8a2012-04-23 18:22:09 -0700899 private static Message getPostMessage(Runnable r, Object token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 Message m = Message.obtain();
901 m.obj = token;
902 m.callback = r;
903 return m;
904 }
905
Romain Guyba6be8a2012-04-23 18:22:09 -0700906 private static void handleCallback(Message message) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 message.callback.run();
908 }
909
Andrei Onea24ec3212019-03-15 17:35:05 +0000910 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 final Looper mLooper;
Jeff Sharkey74cd3de2016-04-06 17:40:54 -0600912 final MessageQueue mQueue;
Andrei Onea24ec3212019-03-15 17:35:05 +0000913 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 final Callback mCallback;
Jeff Brown109025d2012-08-14 20:41:30 -0700915 final boolean mAsynchronous;
Andrei Onea24ec3212019-03-15 17:35:05 +0000916 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 IMessenger mMessenger;
Jeff Brownc53abc42012-08-29 04:43:25 -0700918
919 private static final class BlockingRunnable implements Runnable {
920 private final Runnable mTask;
921 private boolean mDone;
922
923 public BlockingRunnable(Runnable task) {
924 mTask = task;
925 }
926
927 @Override
928 public void run() {
929 try {
930 mTask.run();
931 } finally {
932 synchronized (this) {
933 mDone = true;
934 notifyAll();
935 }
936 }
937 }
938
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700939 public boolean postAndWait(Handler handler, long timeout) {
Jeff Brownc53abc42012-08-29 04:43:25 -0700940 if (!handler.post(this)) {
941 return false;
942 }
943
944 synchronized (this) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700945 if (timeout > 0) {
946 final long expirationTime = SystemClock.uptimeMillis() + timeout;
947 while (!mDone) {
948 long delay = expirationTime - SystemClock.uptimeMillis();
949 if (delay <= 0) {
950 return false; // timeout
951 }
952 try {
953 wait(delay);
954 } catch (InterruptedException ex) {
955 }
956 }
957 } else {
958 while (!mDone) {
959 try {
960 wait();
961 } catch (InterruptedException ex) {
962 }
Jeff Brownc53abc42012-08-29 04:43:25 -0700963 }
964 }
965 }
966 return true;
967 }
968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969}