blob: 45a9cf5ab869e4fb94b6e1b06101e3c8c4e031f0 [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
31 * queue. When you create a new Handler, it is bound to the thread /
32 * message queue of the thread that is creating it -- from that point on,
33 * it will deliver messages and runnables to that message queue and execute
34 * them as they come out of the message queue.
35 *
36 * <p>There are two main uses for a Handler: (1) to schedule messages and
kopriva9b5c0392018-09-10 14:02:58 -070037 * runnables to be executed at some point in the future; and (2) to enqueue
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038 * an action to be performed on a different thread than your own.
39 *
40 * <p>Scheduling messages is accomplished with the
41 * {@link #post}, {@link #postAtTime(Runnable, long)},
42 * {@link #postDelayed}, {@link #sendEmptyMessage},
43 * {@link #sendMessage}, {@link #sendMessageAtTime}, and
44 * {@link #sendMessageDelayed} methods. The <em>post</em> versions allow
45 * you to enqueue Runnable objects to be called by the message queue when
46 * they are received; the <em>sendMessage</em> versions allow you to enqueue
47 * a {@link Message} object containing a bundle of data that will be
48 * processed by the Handler's {@link #handleMessage} method (requiring that
49 * you implement a subclass of Handler).
50 *
51 * <p>When posting or sending to a Handler, you can either
52 * allow the item to be processed as soon as the message queue is ready
53 * to do so, or specify a delay before it gets processed or absolute time for
54 * it to be processed. The latter two allow you to implement timeouts,
55 * ticks, and other timing-based behavior.
56 *
57 * <p>When a
58 * process is created for your application, its main thread is dedicated to
59 * running a message queue that takes care of managing the top-level
60 * application objects (activities, broadcast receivers, etc) and any windows
61 * they create. You can create your own threads, and communicate back with
62 * the main application thread through a Handler. This is done by calling
63 * the same <em>post</em> or <em>sendMessage</em> methods as before, but from
Chris Palmer42855142010-09-09 17:04:31 -070064 * your new thread. The given Runnable or Message will then be scheduled
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 * in the Handler's message queue and processed when appropriate.
66 */
67public class Handler {
68 /*
69 * Set this flag to true to detect anonymous, local or member classes
70 * that extend this Handler class and that are not static. These kind
71 * of classes can potentially create leaks.
72 */
73 private static final boolean FIND_POTENTIAL_LEAKS = false;
74 private static final String TAG = "Handler";
Eugene Suslaa38fbf62017-03-14 10:26:10 -070075 private static Handler MAIN_THREAD_HANDLER = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
77 /**
78 * Callback interface you can use when instantiating a Handler to avoid
79 * having to implement your own subclass of Handler.
80 */
81 public interface Callback {
Pavel Grafovdcc53572017-03-10 19:39:14 +000082 /**
83 * @param msg A {@link android.os.Message Message} object
84 * @return True if no further handling is desired
85 */
Jake Wharton720530b2019-03-08 12:05:53 -050086 boolean handleMessage(@NonNull Message msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 }
88
89 /**
90 * Subclasses must implement this to receive messages.
91 */
Jake Wharton720530b2019-03-08 12:05:53 -050092 public void handleMessage(@NonNull Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 }
94
95 /**
96 * Handle system messages here.
97 */
Jake Wharton720530b2019-03-08 12:05:53 -050098 public void dispatchMessage(@NonNull Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 if (msg.callback != null) {
100 handleCallback(msg);
101 } else {
102 if (mCallback != null) {
103 if (mCallback.handleMessage(msg)) {
104 return;
105 }
106 }
107 handleMessage(msg);
108 }
109 }
110
111 /**
Jeff Browna2910d02012-08-25 12:29:46 -0700112 * Default constructor associates this handler with the {@link Looper} for the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 * current thread.
114 *
Jeff Browna2910d02012-08-25 12:29:46 -0700115 * If this thread does not have a looper, this handler won't be able to receive messages
116 * so an exception is thrown.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 */
118 public Handler() {
Jeff Browna2910d02012-08-25 12:29:46 -0700119 this(null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 }
121
122 /**
Jeff Browna2910d02012-08-25 12:29:46 -0700123 * Constructor associates this handler with the {@link Looper} for the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 * current thread and takes a callback interface in which you can handle
125 * messages.
Jeff Browna2910d02012-08-25 12:29:46 -0700126 *
127 * If this thread does not have a looper, this handler won't be able to receive messages
128 * so an exception is thrown.
129 *
130 * @param callback The callback interface in which to handle messages, or null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 */
Jake Wharton720530b2019-03-08 12:05:53 -0500132 public Handler(@Nullable Callback callback) {
Jeff Browna2910d02012-08-25 12:29:46 -0700133 this(callback, false);
134 }
135
136 /**
137 * Use the provided {@link Looper} instead of the default one.
138 *
139 * @param looper The looper, must not be null.
140 */
Jake Wharton720530b2019-03-08 12:05:53 -0500141 public Handler(@NonNull Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -0700142 this(looper, null, false);
143 }
144
145 /**
146 * Use the provided {@link Looper} instead of the default one and take a callback
147 * interface in which to handle messages.
148 *
149 * @param looper The looper, must not be null.
150 * @param callback The callback interface in which to handle messages, or null.
151 */
Jake Wharton720530b2019-03-08 12:05:53 -0500152 public Handler(@NonNull Looper looper, @Nullable Callback callback) {
Jeff Browna2910d02012-08-25 12:29:46 -0700153 this(looper, callback, false);
154 }
155
156 /**
157 * Use the {@link Looper} for the current thread
158 * and set whether the handler should be asynchronous.
159 *
160 * Handlers are synchronous by default unless this constructor is used to make
161 * one that is strictly asynchronous.
162 *
163 * Asynchronous messages represent interrupts or events that do not require global ordering
Jeff Brown9840c072014-11-11 20:21:21 -0800164 * with respect to synchronous messages. Asynchronous messages are not subject to
Jeff Browna2910d02012-08-25 12:29:46 -0700165 * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
166 *
167 * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
168 * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
169 *
170 * @hide
171 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000172 @UnsupportedAppUsage
Jeff Browna2910d02012-08-25 12:29:46 -0700173 public Handler(boolean async) {
174 this(null, async);
175 }
176
177 /**
178 * Use the {@link Looper} for the current thread with the specified callback interface
179 * and set whether the handler should be asynchronous.
180 *
181 * Handlers are synchronous by default unless this constructor is used to make
182 * one that is strictly asynchronous.
183 *
184 * Asynchronous messages represent interrupts or events that do not require global ordering
Jeff Brown9840c072014-11-11 20:21:21 -0800185 * with respect to synchronous messages. Asynchronous messages are not subject to
Jeff Browna2910d02012-08-25 12:29:46 -0700186 * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
187 *
188 * @param callback The callback interface in which to handle messages, or null.
189 * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
190 * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
191 *
192 * @hide
193 */
Jake Wharton720530b2019-03-08 12:05:53 -0500194 public Handler(@Nullable Callback callback, boolean async) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 if (FIND_POTENTIAL_LEAKS) {
196 final Class<? extends Handler> klass = getClass();
197 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
198 (klass.getModifiers() & Modifier.STATIC) == 0) {
199 Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
200 klass.getCanonicalName());
201 }
202 }
203
204 mLooper = Looper.myLooper();
205 if (mLooper == null) {
206 throw new RuntimeException(
Eugene Susla8f07ee12017-11-14 17:41:03 -0800207 "Can't create handler inside thread " + Thread.currentThread()
208 + " that has not called Looper.prepare()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 }
210 mQueue = mLooper.mQueue;
211 mCallback = callback;
Jeff Browna2910d02012-08-25 12:29:46 -0700212 mAsynchronous = async;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 }
214
215 /**
Jeff Browna2910d02012-08-25 12:29:46 -0700216 * Use the provided {@link Looper} instead of the default one and take a callback
Jeff Brown109025d2012-08-14 20:41:30 -0700217 * interface in which to handle messages. Also set whether the handler
218 * should be asynchronous.
219 *
220 * Handlers are synchronous by default unless this constructor is used to make
221 * one that is strictly asynchronous.
222 *
223 * Asynchronous messages represent interrupts or events that do not require global ordering
Jeff Brown9840c072014-11-11 20:21:21 -0800224 * with respect to synchronous messages. Asynchronous messages are not subject to
Adam Powell8709ba82018-02-21 10:18:25 -0800225 * the synchronization barriers introduced by conditions such as display vsync.
Jeff Brown109025d2012-08-14 20:41:30 -0700226 *
Jeff Browna2910d02012-08-25 12:29:46 -0700227 * @param looper The looper, must not be null.
228 * @param callback The callback interface in which to handle messages, or null.
Jeff Brown109025d2012-08-14 20:41:30 -0700229 * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
230 * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
231 *
232 * @hide
233 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000234 @UnsupportedAppUsage
Jake Wharton720530b2019-03-08 12:05:53 -0500235 public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
Jeff Brown109025d2012-08-14 20:41:30 -0700236 mLooper = looper;
237 mQueue = looper.mQueue;
238 mCallback = callback;
239 mAsynchronous = async;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 }
241
Adam Powell8709ba82018-02-21 10:18:25 -0800242 /**
243 * Create a new Handler whose posted messages and runnables are not subject to
244 * synchronization barriers such as display vsync.
245 *
246 * <p>Messages sent to an async handler are guaranteed to be ordered with respect to one another,
247 * but not necessarily with respect to messages from other Handlers.</p>
248 *
249 * @see #createAsync(Looper, Callback) to create an async Handler with custom message handling.
250 *
251 * @param looper the Looper that the new Handler should be bound to
252 * @return a new async Handler instance
253 */
254 @NonNull
255 public static Handler createAsync(@NonNull Looper looper) {
256 if (looper == null) throw new NullPointerException("looper must not be null");
257 return new Handler(looper, null, true);
258 }
259
260 /**
261 * Create a new Handler whose posted messages and runnables are not subject to
262 * synchronization barriers such as display vsync.
263 *
264 * <p>Messages sent to an async handler are guaranteed to be ordered with respect to one another,
265 * but not necessarily with respect to messages from other Handlers.</p>
266 *
267 * @see #createAsync(Looper) to create an async Handler without custom message handling.
268 *
269 * @param looper the Looper that the new Handler should be bound to
270 * @return a new async Handler instance
271 */
272 @NonNull
273 public static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) {
274 if (looper == null) throw new NullPointerException("looper must not be null");
275 if (callback == null) throw new NullPointerException("callback must not be null");
276 return new Handler(looper, callback, true);
277 }
278
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700279 /** @hide */
Andrei Onea24ec3212019-03-15 17:35:05 +0000280 @UnsupportedAppUsage
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700281 @NonNull
282 public static Handler getMain() {
283 if (MAIN_THREAD_HANDLER == null) {
284 MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper());
285 }
286 return MAIN_THREAD_HANDLER;
287 }
288
289 /** @hide */
290 @NonNull
291 public static Handler mainIfNull(@Nullable Handler handler) {
292 return handler == null ? getMain() : handler;
293 }
294
Jeff Sharkey74cd3de2016-04-06 17:40:54 -0600295 /** {@hide} */
Jake Wharton720530b2019-03-08 12:05:53 -0500296 @NonNull
297 public String getTraceName(@NonNull Message message) {
Felipe Leme4bc790d2019-09-16 17:52:07 -0700298 if (message.callback instanceof TraceNameSupplier) {
299 return ((TraceNameSupplier) message.callback).getTraceName();
300 }
301
Jeff Sharkey74cd3de2016-04-06 17:40:54 -0600302 final StringBuilder sb = new StringBuilder();
303 sb.append(getClass().getName()).append(": ");
304 if (message.callback != null) {
305 sb.append(message.callback.getClass().getName());
306 } else {
307 sb.append("#").append(message.what);
308 }
309 return sb.toString();
310 }
311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 /**
Romain Guyf9284692011-07-13 18:46:21 -0700313 * Returns a string representing the name of the specified message.
314 * The default implementation will either return the class name of the
315 * message callback if any, or the hexadecimal representation of the
316 * message "what" field.
317 *
318 * @param message The message whose name is being queried
319 */
Jake Wharton720530b2019-03-08 12:05:53 -0500320 @NonNull
321 public String getMessageName(@NonNull Message message) {
Romain Guyf9284692011-07-13 18:46:21 -0700322 if (message.callback != null) {
323 return message.callback.getClass().getName();
324 }
325 return "0x" + Integer.toHexString(message.what);
326 }
327
328 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
330 * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
331 * If you don't want that facility, just call Message.obtain() instead.
332 */
Jake Wharton720530b2019-03-08 12:05:53 -0500333 @NonNull
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 public final Message obtainMessage()
335 {
336 return Message.obtain(this);
337 }
338
339 /**
340 * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message.
341 *
342 * @param what Value to assign to the returned Message.what field.
343 * @return A Message from the global message pool.
344 */
Jake Wharton720530b2019-03-08 12:05:53 -0500345 @NonNull
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 public final Message obtainMessage(int what)
347 {
348 return Message.obtain(this, what);
349 }
350
351 /**
352 *
353 * Same as {@link #obtainMessage()}, except that it also sets the what and obj members
354 * of the returned Message.
355 *
356 * @param what Value to assign to the returned Message.what field.
357 * @param obj Value to assign to the returned Message.obj field.
358 * @return A Message from the global message pool.
359 */
Jake Wharton720530b2019-03-08 12:05:53 -0500360 @NonNull
361 public final Message obtainMessage(int what, @Nullable Object obj) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 return Message.obtain(this, what, obj);
363 }
364
365 /**
366 *
367 * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned
368 * Message.
369 * @param what Value to assign to the returned Message.what field.
370 * @param arg1 Value to assign to the returned Message.arg1 field.
371 * @param arg2 Value to assign to the returned Message.arg2 field.
372 * @return A Message from the global message pool.
373 */
Jake Wharton720530b2019-03-08 12:05:53 -0500374 @NonNull
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 public final Message obtainMessage(int what, int arg1, int arg2)
376 {
377 return Message.obtain(this, what, arg1, arg2);
378 }
379
380 /**
381 *
382 * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the
383 * returned Message.
384 * @param what Value to assign to the returned Message.what field.
385 * @param arg1 Value to assign to the returned Message.arg1 field.
386 * @param arg2 Value to assign to the returned Message.arg2 field.
387 * @param obj Value to assign to the returned Message.obj field.
388 * @return A Message from the global message pool.
389 */
Jake Wharton720530b2019-03-08 12:05:53 -0500390 @NonNull
391 public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 return Message.obtain(this, what, arg1, arg2, obj);
393 }
394
395 /**
396 * Causes the Runnable r to be added to the message queue.
397 * The runnable will be run on the thread to which this handler is
398 * attached.
399 *
400 * @param r The Runnable that will be executed.
401 *
402 * @return Returns true if the Runnable was successfully placed in to the
403 * message queue. Returns false on failure, usually because the
404 * looper processing the message queue is exiting.
405 */
Jake Wharton720530b2019-03-08 12:05:53 -0500406 public final boolean post(@NonNull Runnable r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 return sendMessageDelayed(getPostMessage(r), 0);
408 }
409
410 /**
411 * Causes the Runnable r to be added to the message queue, to be run
412 * at a specific time given by <var>uptimeMillis</var>.
413 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
David Christiea8cf4f22013-12-19 18:30:06 -0800414 * Time spent in deep sleep will add an additional delay to execution.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 * The runnable will be run on the thread to which this handler is attached.
416 *
417 * @param r The Runnable that will be executed.
418 * @param uptimeMillis The absolute time at which the callback should run,
419 * using the {@link android.os.SystemClock#uptimeMillis} time-base.
420 *
421 * @return Returns true if the Runnable was successfully placed in to the
422 * message queue. Returns false on failure, usually because the
423 * looper processing the message queue is exiting. Note that a
424 * result of true does not mean the Runnable will be processed -- if
425 * the looper is quit before the delivery time of the message
426 * occurs then the message will be dropped.
427 */
Jake Wharton720530b2019-03-08 12:05:53 -0500428 public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 return sendMessageAtTime(getPostMessage(r), uptimeMillis);
430 }
431
432 /**
433 * Causes the Runnable r to be added to the message queue, to be run
434 * at a specific time given by <var>uptimeMillis</var>.
435 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
David Christiea8cf4f22013-12-19 18:30:06 -0800436 * Time spent in deep sleep will add an additional delay to execution.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 * The runnable will be run on the thread to which this handler is attached.
438 *
439 * @param r The Runnable that will be executed.
Jake Wharton820e3dd2018-01-02 22:18:24 -0500440 * @param token An instance which can be used to cancel {@code r} via
441 * {@link #removeCallbacksAndMessages}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 * @param uptimeMillis The absolute time at which the callback should run,
443 * using the {@link android.os.SystemClock#uptimeMillis} time-base.
444 *
445 * @return Returns true if the Runnable was successfully placed in to the
446 * message queue. Returns false on failure, usually because the
447 * looper processing the message queue is exiting. Note that a
448 * result of true does not mean the Runnable will be processed -- if
449 * the looper is quit before the delivery time of the message
450 * occurs then the message will be dropped.
451 *
452 * @see android.os.SystemClock#uptimeMillis
453 */
Jake Wharton720530b2019-03-08 12:05:53 -0500454 public final boolean postAtTime(
455 @NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
457 }
458
459 /**
460 * Causes the Runnable r to be added to the message queue, to be run
461 * after the specified amount of time elapses.
462 * The runnable will be run on the thread to which this handler
463 * is attached.
David Christiea8cf4f22013-12-19 18:30:06 -0800464 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
465 * Time spent in deep sleep will add an additional delay to execution.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 *
467 * @param r The Runnable that will be executed.
468 * @param delayMillis The delay (in milliseconds) until the Runnable
469 * will be executed.
470 *
471 * @return Returns true if the Runnable was successfully placed in to the
472 * message queue. Returns false on failure, usually because the
473 * looper processing the message queue is exiting. Note that a
474 * result of true does not mean the Runnable will be processed --
475 * if the looper is quit before the delivery time of the message
476 * occurs then the message will be dropped.
477 */
Jake Wharton720530b2019-03-08 12:05:53 -0500478 public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 return sendMessageDelayed(getPostMessage(r), delayMillis);
480 }
481
Felipe Leme3fe6e922019-02-04 17:52:27 -0800482 /** @hide */
483 public final boolean postDelayed(Runnable r, int what, long delayMillis) {
484 return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
485 }
486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 /**
Jake Wharton820e3dd2018-01-02 22:18:24 -0500488 * Causes the Runnable r to be added to the message queue, to be run
489 * after the specified amount of time elapses.
490 * The runnable will be run on the thread to which this handler
491 * is attached.
492 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
493 * Time spent in deep sleep will add an additional delay to execution.
494 *
495 * @param r The Runnable that will be executed.
496 * @param token An instance which can be used to cancel {@code r} via
497 * {@link #removeCallbacksAndMessages}.
498 * @param delayMillis The delay (in milliseconds) until the Runnable
499 * will be executed.
500 *
501 * @return Returns true if the Runnable was successfully placed in to the
502 * message queue. Returns false on failure, usually because the
503 * looper processing the message queue is exiting. Note that a
504 * result of true does not mean the Runnable will be processed --
505 * if the looper is quit before the delivery time of the message
506 * occurs then the message will be dropped.
507 */
Jake Wharton720530b2019-03-08 12:05:53 -0500508 public final boolean postDelayed(
509 @NonNull Runnable r, @Nullable Object token, long delayMillis) {
Jake Wharton820e3dd2018-01-02 22:18:24 -0500510 return sendMessageDelayed(getPostMessage(r, token), delayMillis);
511 }
512
513 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 * Posts a message to an object that implements Runnable.
515 * Causes the Runnable r to executed on the next iteration through the
516 * message queue. The runnable will be run on the thread to which this
517 * handler is attached.
518 * <b>This method is only for use in very special circumstances -- it
519 * can easily starve the message queue, cause ordering problems, or have
520 * other unexpected side-effects.</b>
521 *
522 * @param r The Runnable that will be executed.
523 *
524 * @return Returns true if the message was successfully placed in to the
525 * message queue. Returns false on failure, usually because the
526 * looper processing the message queue is exiting.
527 */
Jake Wharton720530b2019-03-08 12:05:53 -0500528 public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 return sendMessageAtFrontOfQueue(getPostMessage(r));
530 }
531
532 /**
Jeff Brownc53abc42012-08-29 04:43:25 -0700533 * Runs the specified task synchronously.
Jeff Brown8b60e452013-04-18 15:17:48 -0700534 * <p>
Jeff Brownc53abc42012-08-29 04:43:25 -0700535 * If the current thread is the same as the handler thread, then the runnable
536 * runs immediately without being enqueued. Otherwise, posts the runnable
537 * to the handler and waits for it to complete before returning.
Jeff Brown8b60e452013-04-18 15:17:48 -0700538 * </p><p>
Jeff Brownc53abc42012-08-29 04:43:25 -0700539 * This method is dangerous! Improper use can result in deadlocks.
540 * Never call this method while any locks are held or use it in a
541 * possibly re-entrant manner.
Jeff Brown8b60e452013-04-18 15:17:48 -0700542 * </p><p>
Jeff Brownc53abc42012-08-29 04:43:25 -0700543 * This method is occasionally useful in situations where a background thread
544 * must synchronously await completion of a task that must run on the
545 * handler's thread. However, this problem is often a symptom of bad design.
546 * Consider improving the design (if possible) before resorting to this method.
Jeff Brown8b60e452013-04-18 15:17:48 -0700547 * </p><p>
Jeff Brownc53abc42012-08-29 04:43:25 -0700548 * One example of where you might want to use this method is when you just
549 * set up a Handler thread and need to perform some initialization steps on
550 * it before continuing execution.
Jeff Brown8b60e452013-04-18 15:17:48 -0700551 * </p><p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700552 * If timeout occurs then this method returns <code>false</code> but the runnable
553 * will remain posted on the handler and may already be in progress or
554 * complete at a later time.
Jeff Brown8b60e452013-04-18 15:17:48 -0700555 * </p><p>
556 * When using this method, be sure to use {@link Looper#quitSafely} when
557 * quitting the looper. Otherwise {@link #runWithScissors} may hang indefinitely.
558 * (TODO: We should fix this by making MessageQueue aware of blocking runnables.)
559 * </p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700560 *
Jeff Brownc53abc42012-08-29 04:43:25 -0700561 * @param r The Runnable that will be executed synchronously.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700562 * @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
Jeff Brownc53abc42012-08-29 04:43:25 -0700563 *
564 * @return Returns true if the Runnable was successfully executed.
565 * Returns false on failure, usually because the
566 * looper processing the message queue is exiting.
567 *
568 * @hide This method is prone to abuse and should probably not be in the API.
569 * If we ever do make it part of the API, we might want to rename it to something
570 * less funny like runUnsafe().
571 */
Jake Wharton720530b2019-03-08 12:05:53 -0500572 public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
Jeff Brownc53abc42012-08-29 04:43:25 -0700573 if (r == null) {
574 throw new IllegalArgumentException("runnable must not be null");
575 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700576 if (timeout < 0) {
577 throw new IllegalArgumentException("timeout must be non-negative");
578 }
Jeff Brownc53abc42012-08-29 04:43:25 -0700579
580 if (Looper.myLooper() == mLooper) {
581 r.run();
582 return true;
583 }
584
585 BlockingRunnable br = new BlockingRunnable(r);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700586 return br.postAndWait(this, timeout);
Jeff Brownc53abc42012-08-29 04:43:25 -0700587 }
588
589 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 * Remove any pending posts of Runnable r that are in the message queue.
591 */
Jake Wharton720530b2019-03-08 12:05:53 -0500592 public final void removeCallbacks(@NonNull Runnable r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 mQueue.removeMessages(this, r, null);
594 }
595
596 /**
597 * Remove any pending posts of Runnable <var>r</var> with Object
Dianne Hackborn466ed242011-07-21 18:16:31 -0700598 * <var>token</var> that are in the message queue. If <var>token</var> is null,
599 * all callbacks will be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 */
Jake Wharton720530b2019-03-08 12:05:53 -0500601 public final void removeCallbacks(@NonNull Runnable r, @Nullable Object token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 mQueue.removeMessages(this, r, token);
603 }
604
605 /**
606 * Pushes a message onto the end of the message queue after all pending messages
607 * before the current time. It will be received in {@link #handleMessage},
608 * in the thread attached to this handler.
609 *
610 * @return Returns true if the message was successfully placed in to the
611 * message queue. Returns false on failure, usually because the
612 * looper processing the message queue is exiting.
613 */
Jake Wharton720530b2019-03-08 12:05:53 -0500614 public final boolean sendMessage(@NonNull Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 return sendMessageDelayed(msg, 0);
616 }
617
618 /**
619 * Sends a Message containing only the what value.
620 *
621 * @return Returns true if the message was successfully placed in to the
622 * message queue. Returns false on failure, usually because the
623 * looper processing the message queue is exiting.
624 */
625 public final boolean sendEmptyMessage(int what)
626 {
627 return sendEmptyMessageDelayed(what, 0);
628 }
629
630 /**
631 * Sends a Message containing only the what value, to be delivered
632 * after the specified amount of time elapses.
633 * @see #sendMessageDelayed(android.os.Message, long)
634 *
635 * @return Returns true if the message was successfully placed in to the
636 * message queue. Returns false on failure, usually because the
637 * looper processing the message queue is exiting.
638 */
639 public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
640 Message msg = Message.obtain();
641 msg.what = what;
642 return sendMessageDelayed(msg, delayMillis);
643 }
644
645 /**
646 * Sends a Message containing only the what value, to be delivered
647 * at a specific time.
648 * @see #sendMessageAtTime(android.os.Message, long)
649 *
650 * @return Returns true if the message was successfully placed in to the
651 * message queue. Returns false on failure, usually because the
652 * looper processing the message queue is exiting.
653 */
654
655 public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
656 Message msg = Message.obtain();
657 msg.what = what;
658 return sendMessageAtTime(msg, uptimeMillis);
659 }
660
661 /**
662 * Enqueue a message into the message queue after all pending messages
663 * before (current time + delayMillis). You will receive it in
664 * {@link #handleMessage}, in the thread attached to this handler.
665 *
666 * @return Returns true if the message was successfully placed in to the
667 * message queue. Returns false on failure, usually because the
668 * looper processing the message queue is exiting. Note that a
669 * result of true does not mean the message will be processed -- if
670 * the looper is quit before the delivery time of the message
671 * occurs then the message will be dropped.
672 */
Jake Wharton720530b2019-03-08 12:05:53 -0500673 public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 if (delayMillis < 0) {
675 delayMillis = 0;
676 }
677 return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
678 }
679
680 /**
681 * Enqueue a message into the message queue after all pending messages
682 * before the absolute time (in milliseconds) <var>uptimeMillis</var>.
683 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
David Christiea8cf4f22013-12-19 18:30:06 -0800684 * Time spent in deep sleep will add an additional delay to execution.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685 * You will receive it in {@link #handleMessage}, in the thread attached
686 * to this handler.
687 *
688 * @param uptimeMillis The absolute time at which the message should be
689 * delivered, using the
690 * {@link android.os.SystemClock#uptimeMillis} time-base.
691 *
692 * @return Returns true if the message was successfully placed in to the
693 * message queue. Returns false on failure, usually because the
694 * looper processing the message queue is exiting. Note that a
695 * result of true does not mean the message will be processed -- if
696 * the looper is quit before the delivery time of the message
697 * occurs then the message will be dropped.
698 */
Jake Wharton720530b2019-03-08 12:05:53 -0500699 public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 MessageQueue queue = mQueue;
Jeff Brown109025d2012-08-14 20:41:30 -0700701 if (queue == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 RuntimeException e = new RuntimeException(
Jeff Brown109025d2012-08-14 20:41:30 -0700703 this + " sendMessageAtTime() called with no mQueue");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 Log.w("Looper", e.getMessage(), e);
Jeff Brown109025d2012-08-14 20:41:30 -0700705 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800706 }
Jeff Brown109025d2012-08-14 20:41:30 -0700707 return enqueueMessage(queue, msg, uptimeMillis);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 }
709
710 /**
711 * Enqueue a message at the front of the message queue, to be processed on
712 * the next iteration of the message loop. You will receive it in
713 * {@link #handleMessage}, in the thread attached to this handler.
714 * <b>This method is only for use in very special circumstances -- it
715 * can easily starve the message queue, cause ordering problems, or have
716 * other unexpected side-effects.</b>
717 *
718 * @return Returns true if the message was successfully placed in to the
719 * message queue. Returns false on failure, usually because the
720 * looper processing the message queue is exiting.
721 */
Jake Wharton720530b2019-03-08 12:05:53 -0500722 public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 MessageQueue queue = mQueue;
Jeff Brown109025d2012-08-14 20:41:30 -0700724 if (queue == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800725 RuntimeException e = new RuntimeException(
726 this + " sendMessageAtTime() called with no mQueue");
727 Log.w("Looper", e.getMessage(), e);
Jeff Brown109025d2012-08-14 20:41:30 -0700728 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729 }
Jeff Brown109025d2012-08-14 20:41:30 -0700730 return enqueueMessage(queue, msg, 0);
731 }
732
Eugene Susla9f35ca92018-02-12 16:17:26 -0800733 /**
734 * Executes the message synchronously if called on the same thread this handler corresponds to,
735 * or {@link #sendMessage pushes it to the queue} otherwise
736 *
737 * @return Returns true if the message was successfully ran or placed in to the
738 * message queue. Returns false on failure, usually because the
739 * looper processing the message queue is exiting.
740 * @hide
741 */
Jake Wharton720530b2019-03-08 12:05:53 -0500742 public final boolean executeOrSendMessage(@NonNull Message msg) {
Eugene Susla9f35ca92018-02-12 16:17:26 -0800743 if (mLooper == Looper.myLooper()) {
744 dispatchMessage(msg);
745 return true;
746 }
747 return sendMessage(msg);
748 }
749
Jake Wharton720530b2019-03-08 12:05:53 -0500750 private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
751 long uptimeMillis) {
Jeff Brown109025d2012-08-14 20:41:30 -0700752 msg.target = this;
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000753 msg.workSourceUid = ThreadLocalWorkSource.getUid();
Marcin Oczeretkoec758722018-09-12 12:53:47 +0100754
Jeff Brown109025d2012-08-14 20:41:30 -0700755 if (mAsynchronous) {
756 msg.setAsynchronous(true);
757 }
758 return queue.enqueueMessage(msg, uptimeMillis);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759 }
760
761 /**
762 * Remove any pending posts of messages with code 'what' that are in the
763 * message queue.
764 */
765 public final void removeMessages(int what) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800766 mQueue.removeMessages(this, what, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 }
768
769 /**
770 * Remove any pending posts of messages with code 'what' and whose obj is
Jeff Brown32c81132012-04-30 16:28:32 -0700771 * 'object' that are in the message queue. If <var>object</var> is null,
Dianne Hackborn466ed242011-07-21 18:16:31 -0700772 * all messages will be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 */
Jake Wharton720530b2019-03-08 12:05:53 -0500774 public final void removeMessages(int what, @Nullable Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800775 mQueue.removeMessages(this, what, object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 }
777
778 /**
779 * Remove any pending posts of callbacks and sent messages whose
Dianne Hackborn466ed242011-07-21 18:16:31 -0700780 * <var>obj</var> is <var>token</var>. If <var>token</var> is null,
781 * all callbacks and messages will be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 */
Jake Wharton720530b2019-03-08 12:05:53 -0500783 public final void removeCallbacksAndMessages(@Nullable Object token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 mQueue.removeCallbacksAndMessages(this, token);
785 }
786
787 /**
788 * Check if there are any pending posts of messages with code 'what' in
789 * the message queue.
790 */
791 public final boolean hasMessages(int what) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800792 return mQueue.hasMessages(this, what, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 }
794
795 /**
Dianne Hackborncb015632017-06-14 17:30:15 -0700796 * Return whether there are any messages or callbacks currently scheduled on this handler.
797 * @hide
798 */
799 public final boolean hasMessagesOrCallbacks() {
800 return mQueue.hasMessages(this);
801 }
802
803 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 * Check if there are any pending posts of messages with code 'what' and
805 * whose obj is 'object' in the message queue.
806 */
Jake Wharton720530b2019-03-08 12:05:53 -0500807 public final boolean hasMessages(int what, @Nullable Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800808 return mQueue.hasMessages(this, what, object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 }
810
Romain Guyba6be8a2012-04-23 18:22:09 -0700811 /**
812 * Check if there are any pending posts of messages with callback r in
813 * the message queue.
Romain Guyba6be8a2012-04-23 18:22:09 -0700814 */
Jake Wharton720530b2019-03-08 12:05:53 -0500815 public final boolean hasCallbacks(@NonNull Runnable r) {
Romain Guyba6be8a2012-04-23 18:22:09 -0700816 return mQueue.hasMessages(this, r, null);
817 }
818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 // if we can get rid of this method, the handler need not remember its loop
820 // we could instead export a getMessageQueue() method...
Jake Wharton720530b2019-03-08 12:05:53 -0500821 @NonNull
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 public final Looper getLooper() {
823 return mLooper;
824 }
825
Jake Wharton720530b2019-03-08 12:05:53 -0500826 public final void dump(@NonNull Printer pw, @NonNull String prefix) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
828 if (mLooper == null) {
829 pw.println(prefix + "looper uninitialized");
830 } else {
831 mLooper.dump(pw, prefix + " ");
832 }
833 }
834
Dianne Hackborncb015632017-06-14 17:30:15 -0700835 /**
836 * @hide
837 */
Jake Wharton720530b2019-03-08 12:05:53 -0500838 public final void dumpMine(@NonNull Printer pw, @NonNull String prefix) {
Dianne Hackborncb015632017-06-14 17:30:15 -0700839 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
840 if (mLooper == null) {
841 pw.println(prefix + "looper uninitialized");
842 } else {
843 mLooper.dump(pw, prefix + " ", this);
844 }
845 }
846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 @Override
848 public String toString() {
Kristian Monsen588d8562011-08-04 12:55:33 +0100849 return "Handler (" + getClass().getName() + ") {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 + Integer.toHexString(System.identityHashCode(this))
851 + "}";
852 }
853
Andrei Onea24ec3212019-03-15 17:35:05 +0000854 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 final IMessenger getIMessenger() {
856 synchronized (mQueue) {
857 if (mMessenger != null) {
858 return mMessenger;
859 }
860 mMessenger = new MessengerImpl();
861 return mMessenger;
862 }
863 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 private final class MessengerImpl extends IMessenger.Stub {
866 public void send(Message msg) {
Dianne Hackborncb3ed1d2014-06-27 18:37:06 -0700867 msg.sendingUid = Binder.getCallingUid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 Handler.this.sendMessage(msg);
869 }
870 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700871
Romain Guyba6be8a2012-04-23 18:22:09 -0700872 private static Message getPostMessage(Runnable r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 Message m = Message.obtain();
874 m.callback = r;
875 return m;
876 }
877
Andrei Onea24ec3212019-03-15 17:35:05 +0000878 @UnsupportedAppUsage
Romain Guyba6be8a2012-04-23 18:22:09 -0700879 private static Message getPostMessage(Runnable r, Object token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 Message m = Message.obtain();
881 m.obj = token;
882 m.callback = r;
883 return m;
884 }
885
Romain Guyba6be8a2012-04-23 18:22:09 -0700886 private static void handleCallback(Message message) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 message.callback.run();
888 }
889
Andrei Onea24ec3212019-03-15 17:35:05 +0000890 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 final Looper mLooper;
Jeff Sharkey74cd3de2016-04-06 17:40:54 -0600892 final MessageQueue mQueue;
Andrei Onea24ec3212019-03-15 17:35:05 +0000893 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 final Callback mCallback;
Jeff Brown109025d2012-08-14 20:41:30 -0700895 final boolean mAsynchronous;
Andrei Onea24ec3212019-03-15 17:35:05 +0000896 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 IMessenger mMessenger;
Jeff Brownc53abc42012-08-29 04:43:25 -0700898
899 private static final class BlockingRunnable implements Runnable {
900 private final Runnable mTask;
901 private boolean mDone;
902
903 public BlockingRunnable(Runnable task) {
904 mTask = task;
905 }
906
907 @Override
908 public void run() {
909 try {
910 mTask.run();
911 } finally {
912 synchronized (this) {
913 mDone = true;
914 notifyAll();
915 }
916 }
917 }
918
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700919 public boolean postAndWait(Handler handler, long timeout) {
Jeff Brownc53abc42012-08-29 04:43:25 -0700920 if (!handler.post(this)) {
921 return false;
922 }
923
924 synchronized (this) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700925 if (timeout > 0) {
926 final long expirationTime = SystemClock.uptimeMillis() + timeout;
927 while (!mDone) {
928 long delay = expirationTime - SystemClock.uptimeMillis();
929 if (delay <= 0) {
930 return false; // timeout
931 }
932 try {
933 wait(delay);
934 } catch (InterruptedException ex) {
935 }
936 }
937 } else {
938 while (!mDone) {
939 try {
940 wait();
941 } catch (InterruptedException ex) {
942 }
Jeff Brownc53abc42012-08-29 04:43:25 -0700943 }
944 }
945 }
946 return true;
947 }
948 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949}