• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.os;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.compat.annotation.UnsupportedAppUsage;
22 import android.util.Log;
23 import android.util.Printer;
24 
25 import 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 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  *
35  * <p>There are two main uses for a Handler: (1) to schedule messages and
36  * runnables to be executed at some point in the future; and (2) to enqueue
37  * an action to be performed on a different thread than your own.
38  *
39  * <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
63  * your new thread.  The given Runnable or Message will then be scheduled
64  * in the Handler's message queue and processed when appropriate.
65  */
66 public 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";
74     private static Handler MAIN_THREAD_HANDLER = null;
75 
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 {
81         /**
82          * @param msg A {@link android.os.Message Message} object
83          * @return True if no further handling is desired
84          */
handleMessage(@onNull Message msg)85         boolean handleMessage(@NonNull Message msg);
86     }
87 
88     /**
89      * Subclasses must implement this to receive messages.
90      */
handleMessage(@onNull Message msg)91     public void handleMessage(@NonNull Message msg) {
92     }
93 
94     /**
95      * Handle system messages here.
96      */
dispatchMessage(@onNull Message msg)97     public void dispatchMessage(@NonNull Message msg) {
98         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     /**
111      * Default constructor associates this handler with the {@link Looper} for the
112      * current thread.
113      *
114      * If this thread does not have a looper, this handler won't be able to receive messages
115      * so an exception is thrown.
116      *
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      *
126      */
127     @Deprecated
Handler()128     public Handler() {
129         this(null, false);
130     }
131 
132     /**
133      * Constructor associates this handler with the {@link Looper} for the
134      * current thread and takes a callback interface in which you can handle
135      * messages.
136      *
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.
141      *
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.
150      */
151     @Deprecated
Handler(@ullable Callback callback)152     public Handler(@Nullable Callback callback) {
153         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      */
Handler(@onNull Looper looper)161     public Handler(@NonNull Looper looper) {
162         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      */
Handler(@onNull Looper looper, @Nullable Callback callback)172     public Handler(@NonNull Looper looper, @Nullable Callback callback) {
173         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
184      * with respect to synchronous messages.  Asynchronous messages are not subject to
185      * 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      */
192     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Handler(boolean async)193     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
205      * with respect to synchronous messages.  Asynchronous messages are not subject to
206      * 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      */
Handler(@ullable Callback callback, boolean async)214     public Handler(@Nullable Callback callback, boolean async) {
215         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(
227                 "Can't create handler inside thread " + Thread.currentThread()
228                         + " that has not called Looper.prepare()");
229         }
230         mQueue = mLooper.mQueue;
231         mCallback = callback;
232         mAsynchronous = async;
233     }
234 
235     /**
236      * Use the provided {@link Looper} instead of the default one and take a callback
237      * 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
244      * with respect to synchronous messages.  Asynchronous messages are not subject to
245      * the synchronization barriers introduced by conditions such as display vsync.
246      *
247      * @param looper The looper, must not be null.
248      * @param callback The callback interface in which to handle messages, or null.
249      * @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      */
254     @UnsupportedAppUsage
Handler(@onNull Looper looper, @Nullable Callback callback, boolean async)255     public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
256         mLooper = looper;
257         mQueue = looper.mQueue;
258         mCallback = callback;
259         mAsynchronous = async;
260     }
261 
262     /**
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
createAsync(@onNull Looper looper)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
createAsync(@onNull Looper looper, @NonNull Callback callback)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 
299     /** @hide */
300     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
301     @NonNull
getMain()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
mainIfNull(@ullable Handler handler)311     public static Handler mainIfNull(@Nullable Handler handler) {
312         return handler == null ? getMain() : handler;
313     }
314 
315     /** {@hide} */
316     @NonNull
getTraceName(@onNull Message message)317     public String getTraceName(@NonNull Message message) {
318         if (message.callback instanceof TraceNameSupplier) {
319             return ((TraceNameSupplier) message.callback).getTraceName();
320         }
321 
322         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 
332     /**
333      * 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      */
340     @NonNull
getMessageName(@onNull Message message)341     public String getMessageName(@NonNull Message message) {
342         if (message.callback != null) {
343             return message.callback.getClass().getName();
344         }
345         return "0x" + Integer.toHexString(message.what);
346     }
347 
348     /**
349      * 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      */
353     @NonNull
obtainMessage()354     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      */
365     @NonNull
obtainMessage(int what)366     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      */
380     @NonNull
obtainMessage(int what, @Nullable Object obj)381     public final Message obtainMessage(int what, @Nullable Object obj) {
382         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      */
394     @NonNull
obtainMessage(int what, int arg1, int arg2)395     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      */
410     @NonNull
obtainMessage(int what, int arg1, int arg2, @Nullable Object obj)411     public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
412         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      */
post(@onNull Runnable r)426     public final boolean post(@NonNull Runnable r) {
427        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>
434      * Time spent in deep sleep will add an additional delay to execution.
435      * 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      */
postAtTime(@onNull Runnable r, long uptimeMillis)448     public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
449         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>
456      * Time spent in deep sleep will add an additional delay to execution.
457      * The runnable will be run on the thread to which this handler is attached.
458      *
459      * @param r The Runnable that will be executed.
460      * @param token An instance which can be used to cancel {@code r} via
461      *         {@link #removeCallbacksAndMessages}.
462      * @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      */
postAtTime( @onNull Runnable r, @Nullable Object token, long uptimeMillis)474     public final boolean postAtTime(
475             @NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
476         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.
484      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
485      * Time spent in deep sleep will add an additional delay to execution.
486      *
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      */
postDelayed(@onNull Runnable r, long delayMillis)498     public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
499         return sendMessageDelayed(getPostMessage(r), delayMillis);
500     }
501 
502     /** @hide */
postDelayed(Runnable r, int what, long delayMillis)503     public final boolean postDelayed(Runnable r, int what, long delayMillis) {
504         return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
505     }
506 
507     /**
508      * 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      */
postDelayed( @onNull Runnable r, @Nullable Object token, long delayMillis)528     public final boolean postDelayed(
529             @NonNull Runnable r, @Nullable Object token, long delayMillis) {
530         return sendMessageDelayed(getPostMessage(r, token), delayMillis);
531     }
532 
533     /**
534      * 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      */
postAtFrontOfQueue(@onNull Runnable r)548     public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
549         return sendMessageAtFrontOfQueue(getPostMessage(r));
550     }
551 
552     /**
553      * Runs the specified task synchronously.
554      * <p>
555      * 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.
558      * </p><p>
559      * 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.
562      * </p><p>
563      * 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.
567      * </p><p>
568      * 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.
571      * </p><p>
572      * 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.
575      * </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>
580      *
581      * @param r The Runnable that will be executed synchronously.
582      * @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
583      *
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      */
runWithScissors(@onNull Runnable r, long timeout)592     public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
593         if (r == null) {
594             throw new IllegalArgumentException("runnable must not be null");
595         }
596         if (timeout < 0) {
597             throw new IllegalArgumentException("timeout must be non-negative");
598         }
599 
600         if (Looper.myLooper() == mLooper) {
601             r.run();
602             return true;
603         }
604 
605         BlockingRunnable br = new BlockingRunnable(r);
606         return br.postAndWait(this, timeout);
607     }
608 
609     /**
610      * Remove any pending posts of Runnable r that are in the message queue.
611      */
removeCallbacks(@onNull Runnable r)612     public final void removeCallbacks(@NonNull Runnable r) {
613         mQueue.removeMessages(this, r, null);
614     }
615 
616     /**
617      * Remove any pending posts of Runnable <var>r</var> with Object
618      * <var>token</var> that are in the message queue.  If <var>token</var> is null,
619      * all callbacks will be removed.
620      */
removeCallbacks(@onNull Runnable r, @Nullable Object token)621     public final void removeCallbacks(@NonNull Runnable r, @Nullable Object token) {
622         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      */
sendMessage(@onNull Message msg)634     public final boolean sendMessage(@NonNull Message msg) {
635         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      */
sendEmptyMessage(int what)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      */
sendEmptyMessageDelayed(int what, long delayMillis)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 
sendEmptyMessageAtTime(int what, long uptimeMillis)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      */
sendMessageDelayed(@onNull Message msg, long delayMillis)693     public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
694         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>
704      * Time spent in deep sleep will add an additional delay to execution.
705      * 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      */
sendMessageAtTime(@onNull Message msg, long uptimeMillis)719     public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
720         MessageQueue queue = mQueue;
721         if (queue == null) {
722             RuntimeException e = new RuntimeException(
723                     this + " sendMessageAtTime() called with no mQueue");
724             Log.w("Looper", e.getMessage(), e);
725             return false;
726         }
727         return enqueueMessage(queue, msg, uptimeMillis);
728     }
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      */
sendMessageAtFrontOfQueue(@onNull Message msg)742     public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
743         MessageQueue queue = mQueue;
744         if (queue == null) {
745             RuntimeException e = new RuntimeException(
746                 this + " sendMessageAtTime() called with no mQueue");
747             Log.w("Looper", e.getMessage(), e);
748             return false;
749         }
750         return enqueueMessage(queue, msg, 0);
751     }
752 
753     /**
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      */
executeOrSendMessage(@onNull Message msg)762     public final boolean executeOrSendMessage(@NonNull Message msg) {
763         if (mLooper == Looper.myLooper()) {
764             dispatchMessage(msg);
765             return true;
766         }
767         return sendMessage(msg);
768     }
769 
enqueueMessage(@onNull MessageQueue queue, @NonNull Message msg, long uptimeMillis)770     private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
771             long uptimeMillis) {
772         msg.target = this;
773         msg.workSourceUid = ThreadLocalWorkSource.getUid();
774 
775         if (mAsynchronous) {
776             msg.setAsynchronous(true);
777         }
778         return queue.enqueueMessage(msg, uptimeMillis);
779     }
780 
781     /**
782      * Remove any pending posts of messages with code 'what' that are in the
783      * message queue.
784      */
removeMessages(int what)785     public final void removeMessages(int what) {
786         mQueue.removeMessages(this, what, null);
787     }
788 
789     /**
790      * Remove any pending posts of messages with code 'what' and whose obj is
791      * 'object' that are in the message queue.  If <var>object</var> is null,
792      * all messages will be removed.
793      */
removeMessages(int what, @Nullable Object object)794     public final void removeMessages(int what, @Nullable Object object) {
795         mQueue.removeMessages(this, what, object);
796     }
797 
798     /**
799      * Remove any pending posts of messages with code 'what' and whose obj is
800      * 'object' that are in the message queue.  If <var>object</var> is null,
801      * all messages will be removed.
802      *
803      *@hide
804      */
removeEqualMessages(int what, @Nullable Object object)805     public final void removeEqualMessages(int what, @Nullable Object object) {
806         mQueue.removeEqualMessages(this, what, object);
807     }
808 
809     /**
810      * Remove any pending posts of callbacks and sent messages whose
811      * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
812      * all callbacks and messages will be removed.
813      */
removeCallbacksAndMessages(@ullable Object token)814     public final void removeCallbacksAndMessages(@Nullable Object token) {
815         mQueue.removeCallbacksAndMessages(this, token);
816     }
817 
818     /**
819      * Remove any pending posts of callbacks and sent messages whose
820      * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
821      * all callbacks and messages will be removed.
822      *
823      *@hide
824      */
removeCallbacksAndEqualMessages(@ullable Object token)825     public final void removeCallbacksAndEqualMessages(@Nullable Object token) {
826         mQueue.removeCallbacksAndEqualMessages(this, token);
827     }
828     /**
829      * Check if there are any pending posts of messages with code 'what' in
830      * the message queue.
831      */
hasMessages(int what)832     public final boolean hasMessages(int what) {
833         return mQueue.hasMessages(this, what, null);
834     }
835 
836     /**
837      * Return whether there are any messages or callbacks currently scheduled on this handler.
838      * @hide
839      */
hasMessagesOrCallbacks()840     public final boolean hasMessagesOrCallbacks() {
841         return mQueue.hasMessages(this);
842     }
843 
844     /**
845      * Check if there are any pending posts of messages with code 'what' and
846      * whose obj is 'object' in the message queue.
847      */
hasMessages(int what, @Nullable Object object)848     public final boolean hasMessages(int what, @Nullable Object object) {
849         return mQueue.hasMessages(this, what, object);
850     }
851 
852     /**
853      * Check if there are any pending posts of messages with code 'what' and
854      * whose obj is 'object' in the message queue.
855      *
856      *@hide
857      */
hasEqualMessages(int what, @Nullable Object object)858     public final boolean hasEqualMessages(int what, @Nullable Object object) {
859         return mQueue.hasEqualMessages(this, what, object);
860     }
861 
862     /**
863      * Check if there are any pending posts of messages with callback r in
864      * the message queue.
865      */
hasCallbacks(@onNull Runnable r)866     public final boolean hasCallbacks(@NonNull Runnable r) {
867         return mQueue.hasMessages(this, r, null);
868     }
869 
870     // if we can get rid of this method, the handler need not remember its loop
871     // we could instead export a getMessageQueue() method...
872     @NonNull
getLooper()873     public final Looper getLooper() {
874         return mLooper;
875     }
876 
dump(@onNull Printer pw, @NonNull String prefix)877     public final void dump(@NonNull Printer pw, @NonNull String prefix) {
878         pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
879         if (mLooper == null) {
880             pw.println(prefix + "looper uninitialized");
881         } else {
882             mLooper.dump(pw, prefix + "  ");
883         }
884     }
885 
886     /**
887      * @hide
888      */
dumpMine(@onNull Printer pw, @NonNull String prefix)889     public final void dumpMine(@NonNull Printer pw, @NonNull String prefix) {
890         pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
891         if (mLooper == null) {
892             pw.println(prefix + "looper uninitialized");
893         } else {
894             mLooper.dump(pw, prefix + "  ", this);
895         }
896     }
897 
898     @Override
toString()899     public String toString() {
900         return "Handler (" + getClass().getName() + ") {"
901         + Integer.toHexString(System.identityHashCode(this))
902         + "}";
903     }
904 
905     @UnsupportedAppUsage
getIMessenger()906     final IMessenger getIMessenger() {
907         synchronized (mQueue) {
908             if (mMessenger != null) {
909                 return mMessenger;
910             }
911             mMessenger = new MessengerImpl();
912             return mMessenger;
913         }
914     }
915 
916     private final class MessengerImpl extends IMessenger.Stub {
send(Message msg)917         public void send(Message msg) {
918             msg.sendingUid = Binder.getCallingUid();
919             Handler.this.sendMessage(msg);
920         }
921     }
922 
getPostMessage(Runnable r)923     private static Message getPostMessage(Runnable r) {
924         Message m = Message.obtain();
925         m.callback = r;
926         return m;
927     }
928 
929     @UnsupportedAppUsage
getPostMessage(Runnable r, Object token)930     private static Message getPostMessage(Runnable r, Object token) {
931         Message m = Message.obtain();
932         m.obj = token;
933         m.callback = r;
934         return m;
935     }
936 
handleCallback(Message message)937     private static void handleCallback(Message message) {
938         message.callback.run();
939     }
940 
941     @UnsupportedAppUsage
942     final Looper mLooper;
943     final MessageQueue mQueue;
944     @UnsupportedAppUsage
945     final Callback mCallback;
946     final boolean mAsynchronous;
947     @UnsupportedAppUsage
948     IMessenger mMessenger;
949 
950     private static final class BlockingRunnable implements Runnable {
951         private final Runnable mTask;
952         private boolean mDone;
953 
BlockingRunnable(Runnable task)954         public BlockingRunnable(Runnable task) {
955             mTask = task;
956         }
957 
958         @Override
run()959         public void run() {
960             try {
961                 mTask.run();
962             } finally {
963                 synchronized (this) {
964                     mDone = true;
965                     notifyAll();
966                 }
967             }
968         }
969 
postAndWait(Handler handler, long timeout)970         public boolean postAndWait(Handler handler, long timeout) {
971             if (!handler.post(this)) {
972                 return false;
973             }
974 
975             synchronized (this) {
976                 if (timeout > 0) {
977                     final long expirationTime = SystemClock.uptimeMillis() + timeout;
978                     while (!mDone) {
979                         long delay = expirationTime - SystemClock.uptimeMillis();
980                         if (delay <= 0) {
981                             return false; // timeout
982                         }
983                         try {
984                             wait(delay);
985                         } catch (InterruptedException ex) {
986                         }
987                     }
988                 } else {
989                     while (!mDone) {
990                         try {
991                             wait();
992                         } catch (InterruptedException ex) {
993                         }
994                     }
995                 }
996             }
997             return true;
998         }
999     }
1000 }
1001