• 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.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 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
37  * runnables to be executed at some point in the future; and (2) to enqueue
38  * 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
64  * your new thread.  The given Runnable or Message will then be scheduled
65  * in the Handler's message queue and processed when appropriate.
66  */
67 public 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";
75     private static Handler MAIN_THREAD_HANDLER = null;
76 
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 {
82         /**
83          * @param msg A {@link android.os.Message Message} object
84          * @return True if no further handling is desired
85          */
handleMessage(@onNull Message msg)86         boolean handleMessage(@NonNull Message msg);
87     }
88 
89     /**
90      * Subclasses must implement this to receive messages.
91      */
handleMessage(@onNull Message msg)92     public void handleMessage(@NonNull Message msg) {
93     }
94 
95     /**
96      * Handle system messages here.
97      */
dispatchMessage(@onNull Message msg)98     public void dispatchMessage(@NonNull Message msg) {
99         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     /**
112      * Default constructor associates this handler with the {@link Looper} for the
113      * current thread.
114      *
115      * If this thread does not have a looper, this handler won't be able to receive messages
116      * so an exception is thrown.
117      */
Handler()118     public Handler() {
119         this(null, false);
120     }
121 
122     /**
123      * Constructor associates this handler with the {@link Looper} for the
124      * current thread and takes a callback interface in which you can handle
125      * messages.
126      *
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.
131      */
Handler(@ullable Callback callback)132     public Handler(@Nullable Callback callback) {
133         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      */
Handler(@onNull Looper looper)141     public Handler(@NonNull Looper looper) {
142         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      */
Handler(@onNull Looper looper, @Nullable Callback callback)152     public Handler(@NonNull Looper looper, @Nullable Callback callback) {
153         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
164      * with respect to synchronous messages.  Asynchronous messages are not subject to
165      * 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      */
172     @UnsupportedAppUsage
Handler(boolean async)173     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
185      * with respect to synchronous messages.  Asynchronous messages are not subject to
186      * 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      */
Handler(@ullable Callback callback, boolean async)194     public Handler(@Nullable Callback callback, boolean async) {
195         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(
207                 "Can't create handler inside thread " + Thread.currentThread()
208                         + " that has not called Looper.prepare()");
209         }
210         mQueue = mLooper.mQueue;
211         mCallback = callback;
212         mAsynchronous = async;
213     }
214 
215     /**
216      * Use the provided {@link Looper} instead of the default one and take a callback
217      * 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
224      * with respect to synchronous messages.  Asynchronous messages are not subject to
225      * the synchronization barriers introduced by conditions such as display vsync.
226      *
227      * @param looper The looper, must not be null.
228      * @param callback The callback interface in which to handle messages, or null.
229      * @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      */
234     @UnsupportedAppUsage
Handler(@onNull Looper looper, @Nullable Callback callback, boolean async)235     public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
236         mLooper = looper;
237         mQueue = looper.mQueue;
238         mCallback = callback;
239         mAsynchronous = async;
240     }
241 
242     /**
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
createAsync(@onNull Looper looper)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
createAsync(@onNull Looper looper, @NonNull Callback callback)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 
279     /** @hide */
280     @UnsupportedAppUsage
281     @NonNull
getMain()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
mainIfNull(@ullable Handler handler)291     public static Handler mainIfNull(@Nullable Handler handler) {
292         return handler == null ? getMain() : handler;
293     }
294 
295     /** {@hide} */
296     @NonNull
getTraceName(@onNull Message message)297     public String getTraceName(@NonNull Message message) {
298         final StringBuilder sb = new StringBuilder();
299         sb.append(getClass().getName()).append(": ");
300         if (message.callback != null) {
301             sb.append(message.callback.getClass().getName());
302         } else {
303             sb.append("#").append(message.what);
304         }
305         return sb.toString();
306     }
307 
308     /**
309      * Returns a string representing the name of the specified message.
310      * The default implementation will either return the class name of the
311      * message callback if any, or the hexadecimal representation of the
312      * message "what" field.
313      *
314      * @param message The message whose name is being queried
315      */
316     @NonNull
getMessageName(@onNull Message message)317     public String getMessageName(@NonNull Message message) {
318         if (message.callback != null) {
319             return message.callback.getClass().getName();
320         }
321         return "0x" + Integer.toHexString(message.what);
322     }
323 
324     /**
325      * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
326      * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
327      *  If you don't want that facility, just call Message.obtain() instead.
328      */
329     @NonNull
obtainMessage()330     public final Message obtainMessage()
331     {
332         return Message.obtain(this);
333     }
334 
335     /**
336      * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message.
337      *
338      * @param what Value to assign to the returned Message.what field.
339      * @return A Message from the global message pool.
340      */
341     @NonNull
obtainMessage(int what)342     public final Message obtainMessage(int what)
343     {
344         return Message.obtain(this, what);
345     }
346 
347     /**
348      *
349      * Same as {@link #obtainMessage()}, except that it also sets the what and obj members
350      * of the returned Message.
351      *
352      * @param what Value to assign to the returned Message.what field.
353      * @param obj Value to assign to the returned Message.obj field.
354      * @return A Message from the global message pool.
355      */
356     @NonNull
obtainMessage(int what, @Nullable Object obj)357     public final Message obtainMessage(int what, @Nullable Object obj) {
358         return Message.obtain(this, what, obj);
359     }
360 
361     /**
362      *
363      * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned
364      * Message.
365      * @param what Value to assign to the returned Message.what field.
366      * @param arg1 Value to assign to the returned Message.arg1 field.
367      * @param arg2 Value to assign to the returned Message.arg2 field.
368      * @return A Message from the global message pool.
369      */
370     @NonNull
obtainMessage(int what, int arg1, int arg2)371     public final Message obtainMessage(int what, int arg1, int arg2)
372     {
373         return Message.obtain(this, what, arg1, arg2);
374     }
375 
376     /**
377      *
378      * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the
379      * returned Message.
380      * @param what Value to assign to the returned Message.what field.
381      * @param arg1 Value to assign to the returned Message.arg1 field.
382      * @param arg2 Value to assign to the returned Message.arg2 field.
383      * @param obj Value to assign to the returned Message.obj field.
384      * @return A Message from the global message pool.
385      */
386     @NonNull
obtainMessage(int what, int arg1, int arg2, @Nullable Object obj)387     public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
388         return Message.obtain(this, what, arg1, arg2, obj);
389     }
390 
391     /**
392      * Causes the Runnable r to be added to the message queue.
393      * The runnable will be run on the thread to which this handler is
394      * attached.
395      *
396      * @param r The Runnable that will be executed.
397      *
398      * @return Returns true if the Runnable was successfully placed in to the
399      *         message queue.  Returns false on failure, usually because the
400      *         looper processing the message queue is exiting.
401      */
post(@onNull Runnable r)402     public final boolean post(@NonNull Runnable r) {
403        return  sendMessageDelayed(getPostMessage(r), 0);
404     }
405 
406     /**
407      * Causes the Runnable r to be added to the message queue, to be run
408      * at a specific time given by <var>uptimeMillis</var>.
409      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
410      * Time spent in deep sleep will add an additional delay to execution.
411      * The runnable will be run on the thread to which this handler is attached.
412      *
413      * @param r The Runnable that will be executed.
414      * @param uptimeMillis The absolute time at which the callback should run,
415      *         using the {@link android.os.SystemClock#uptimeMillis} time-base.
416      *
417      * @return Returns true if the Runnable was successfully placed in to the
418      *         message queue.  Returns false on failure, usually because the
419      *         looper processing the message queue is exiting.  Note that a
420      *         result of true does not mean the Runnable will be processed -- if
421      *         the looper is quit before the delivery time of the message
422      *         occurs then the message will be dropped.
423      */
postAtTime(@onNull Runnable r, long uptimeMillis)424     public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
425         return sendMessageAtTime(getPostMessage(r), uptimeMillis);
426     }
427 
428     /**
429      * Causes the Runnable r to be added to the message queue, to be run
430      * at a specific time given by <var>uptimeMillis</var>.
431      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
432      * Time spent in deep sleep will add an additional delay to execution.
433      * The runnable will be run on the thread to which this handler is attached.
434      *
435      * @param r The Runnable that will be executed.
436      * @param token An instance which can be used to cancel {@code r} via
437      *         {@link #removeCallbacksAndMessages}.
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      *
448      * @see android.os.SystemClock#uptimeMillis
449      */
postAtTime( @onNull Runnable r, @Nullable Object token, long uptimeMillis)450     public final boolean postAtTime(
451             @NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
452         return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
453     }
454 
455     /**
456      * Causes the Runnable r to be added to the message queue, to be run
457      * after the specified amount of time elapses.
458      * The runnable will be run on the thread to which this handler
459      * is attached.
460      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
461      * Time spent in deep sleep will add an additional delay to execution.
462      *
463      * @param r The Runnable that will be executed.
464      * @param delayMillis The delay (in milliseconds) until the Runnable
465      *        will be executed.
466      *
467      * @return Returns true if the Runnable was successfully placed in to the
468      *         message queue.  Returns false on failure, usually because the
469      *         looper processing the message queue is exiting.  Note that a
470      *         result of true does not mean the Runnable will be processed --
471      *         if the looper is quit before the delivery time of the message
472      *         occurs then the message will be dropped.
473      */
postDelayed(@onNull Runnable r, long delayMillis)474     public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
475         return sendMessageDelayed(getPostMessage(r), delayMillis);
476     }
477 
478     /** @hide */
postDelayed(Runnable r, int what, long delayMillis)479     public final boolean postDelayed(Runnable r, int what, long delayMillis) {
480         return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
481     }
482 
483     /**
484      * Causes the Runnable r to be added to the message queue, to be run
485      * after the specified amount of time elapses.
486      * The runnable will be run on the thread to which this handler
487      * is attached.
488      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
489      * Time spent in deep sleep will add an additional delay to execution.
490      *
491      * @param r The Runnable that will be executed.
492      * @param token An instance which can be used to cancel {@code r} via
493      *         {@link #removeCallbacksAndMessages}.
494      * @param delayMillis The delay (in milliseconds) until the Runnable
495      *        will be executed.
496      *
497      * @return Returns true if the Runnable was successfully placed in to the
498      *         message queue.  Returns false on failure, usually because the
499      *         looper processing the message queue is exiting.  Note that a
500      *         result of true does not mean the Runnable will be processed --
501      *         if the looper is quit before the delivery time of the message
502      *         occurs then the message will be dropped.
503      */
postDelayed( @onNull Runnable r, @Nullable Object token, long delayMillis)504     public final boolean postDelayed(
505             @NonNull Runnable r, @Nullable Object token, long delayMillis) {
506         return sendMessageDelayed(getPostMessage(r, token), delayMillis);
507     }
508 
509     /**
510      * Posts a message to an object that implements Runnable.
511      * Causes the Runnable r to executed on the next iteration through the
512      * message queue. The runnable will be run on the thread to which this
513      * handler is attached.
514      * <b>This method is only for use in very special circumstances -- it
515      * can easily starve the message queue, cause ordering problems, or have
516      * other unexpected side-effects.</b>
517      *
518      * @param r The Runnable that will be executed.
519      *
520      * @return Returns true if the message was successfully placed in to the
521      *         message queue.  Returns false on failure, usually because the
522      *         looper processing the message queue is exiting.
523      */
postAtFrontOfQueue(@onNull Runnable r)524     public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
525         return sendMessageAtFrontOfQueue(getPostMessage(r));
526     }
527 
528     /**
529      * Runs the specified task synchronously.
530      * <p>
531      * If the current thread is the same as the handler thread, then the runnable
532      * runs immediately without being enqueued.  Otherwise, posts the runnable
533      * to the handler and waits for it to complete before returning.
534      * </p><p>
535      * This method is dangerous!  Improper use can result in deadlocks.
536      * Never call this method while any locks are held or use it in a
537      * possibly re-entrant manner.
538      * </p><p>
539      * This method is occasionally useful in situations where a background thread
540      * must synchronously await completion of a task that must run on the
541      * handler's thread.  However, this problem is often a symptom of bad design.
542      * Consider improving the design (if possible) before resorting to this method.
543      * </p><p>
544      * One example of where you might want to use this method is when you just
545      * set up a Handler thread and need to perform some initialization steps on
546      * it before continuing execution.
547      * </p><p>
548      * If timeout occurs then this method returns <code>false</code> but the runnable
549      * will remain posted on the handler and may already be in progress or
550      * complete at a later time.
551      * </p><p>
552      * When using this method, be sure to use {@link Looper#quitSafely} when
553      * quitting the looper.  Otherwise {@link #runWithScissors} may hang indefinitely.
554      * (TODO: We should fix this by making MessageQueue aware of blocking runnables.)
555      * </p>
556      *
557      * @param r The Runnable that will be executed synchronously.
558      * @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
559      *
560      * @return Returns true if the Runnable was successfully executed.
561      *         Returns false on failure, usually because the
562      *         looper processing the message queue is exiting.
563      *
564      * @hide This method is prone to abuse and should probably not be in the API.
565      * If we ever do make it part of the API, we might want to rename it to something
566      * less funny like runUnsafe().
567      */
runWithScissors(@onNull Runnable r, long timeout)568     public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
569         if (r == null) {
570             throw new IllegalArgumentException("runnable must not be null");
571         }
572         if (timeout < 0) {
573             throw new IllegalArgumentException("timeout must be non-negative");
574         }
575 
576         if (Looper.myLooper() == mLooper) {
577             r.run();
578             return true;
579         }
580 
581         BlockingRunnable br = new BlockingRunnable(r);
582         return br.postAndWait(this, timeout);
583     }
584 
585     /**
586      * Remove any pending posts of Runnable r that are in the message queue.
587      */
removeCallbacks(@onNull Runnable r)588     public final void removeCallbacks(@NonNull Runnable r) {
589         mQueue.removeMessages(this, r, null);
590     }
591 
592     /**
593      * Remove any pending posts of Runnable <var>r</var> with Object
594      * <var>token</var> that are in the message queue.  If <var>token</var> is null,
595      * all callbacks will be removed.
596      */
removeCallbacks(@onNull Runnable r, @Nullable Object token)597     public final void removeCallbacks(@NonNull Runnable r, @Nullable Object token) {
598         mQueue.removeMessages(this, r, token);
599     }
600 
601     /**
602      * Pushes a message onto the end of the message queue after all pending messages
603      * before the current time. It will be received in {@link #handleMessage},
604      * in the thread attached to this handler.
605      *
606      * @return Returns true if the message was successfully placed in to the
607      *         message queue.  Returns false on failure, usually because the
608      *         looper processing the message queue is exiting.
609      */
sendMessage(@onNull Message msg)610     public final boolean sendMessage(@NonNull Message msg) {
611         return sendMessageDelayed(msg, 0);
612     }
613 
614     /**
615      * Sends a Message containing only the what value.
616      *
617      * @return Returns true if the message was successfully placed in to the
618      *         message queue.  Returns false on failure, usually because the
619      *         looper processing the message queue is exiting.
620      */
sendEmptyMessage(int what)621     public final boolean sendEmptyMessage(int what)
622     {
623         return sendEmptyMessageDelayed(what, 0);
624     }
625 
626     /**
627      * Sends a Message containing only the what value, to be delivered
628      * after the specified amount of time elapses.
629      * @see #sendMessageDelayed(android.os.Message, long)
630      *
631      * @return Returns true if the message was successfully placed in to the
632      *         message queue.  Returns false on failure, usually because the
633      *         looper processing the message queue is exiting.
634      */
sendEmptyMessageDelayed(int what, long delayMillis)635     public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
636         Message msg = Message.obtain();
637         msg.what = what;
638         return sendMessageDelayed(msg, delayMillis);
639     }
640 
641     /**
642      * Sends a Message containing only the what value, to be delivered
643      * at a specific time.
644      * @see #sendMessageAtTime(android.os.Message, long)
645      *
646      * @return Returns true if the message was successfully placed in to the
647      *         message queue.  Returns false on failure, usually because the
648      *         looper processing the message queue is exiting.
649      */
650 
sendEmptyMessageAtTime(int what, long uptimeMillis)651     public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
652         Message msg = Message.obtain();
653         msg.what = what;
654         return sendMessageAtTime(msg, uptimeMillis);
655     }
656 
657     /**
658      * Enqueue a message into the message queue after all pending messages
659      * before (current time + delayMillis). You will receive it in
660      * {@link #handleMessage}, in the thread attached to this handler.
661      *
662      * @return Returns true if the message was successfully placed in to the
663      *         message queue.  Returns false on failure, usually because the
664      *         looper processing the message queue is exiting.  Note that a
665      *         result of true does not mean the message will be processed -- if
666      *         the looper is quit before the delivery time of the message
667      *         occurs then the message will be dropped.
668      */
sendMessageDelayed(@onNull Message msg, long delayMillis)669     public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
670         if (delayMillis < 0) {
671             delayMillis = 0;
672         }
673         return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
674     }
675 
676     /**
677      * Enqueue a message into the message queue after all pending messages
678      * before the absolute time (in milliseconds) <var>uptimeMillis</var>.
679      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
680      * Time spent in deep sleep will add an additional delay to execution.
681      * You will receive it in {@link #handleMessage}, in the thread attached
682      * to this handler.
683      *
684      * @param uptimeMillis The absolute time at which the message should be
685      *         delivered, using the
686      *         {@link android.os.SystemClock#uptimeMillis} time-base.
687      *
688      * @return Returns true if the message was successfully placed in to the
689      *         message queue.  Returns false on failure, usually because the
690      *         looper processing the message queue is exiting.  Note that a
691      *         result of true does not mean the message will be processed -- if
692      *         the looper is quit before the delivery time of the message
693      *         occurs then the message will be dropped.
694      */
sendMessageAtTime(@onNull Message msg, long uptimeMillis)695     public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
696         MessageQueue queue = mQueue;
697         if (queue == null) {
698             RuntimeException e = new RuntimeException(
699                     this + " sendMessageAtTime() called with no mQueue");
700             Log.w("Looper", e.getMessage(), e);
701             return false;
702         }
703         return enqueueMessage(queue, msg, uptimeMillis);
704     }
705 
706     /**
707      * Enqueue a message at the front of the message queue, to be processed on
708      * the next iteration of the message loop.  You will receive it in
709      * {@link #handleMessage}, in the thread attached to this handler.
710      * <b>This method is only for use in very special circumstances -- it
711      * can easily starve the message queue, cause ordering problems, or have
712      * other unexpected side-effects.</b>
713      *
714      * @return Returns true if the message was successfully placed in to the
715      *         message queue.  Returns false on failure, usually because the
716      *         looper processing the message queue is exiting.
717      */
sendMessageAtFrontOfQueue(@onNull Message msg)718     public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
719         MessageQueue queue = mQueue;
720         if (queue == null) {
721             RuntimeException e = new RuntimeException(
722                 this + " sendMessageAtTime() called with no mQueue");
723             Log.w("Looper", e.getMessage(), e);
724             return false;
725         }
726         return enqueueMessage(queue, msg, 0);
727     }
728 
729     /**
730      * Executes the message synchronously if called on the same thread this handler corresponds to,
731      * or {@link #sendMessage pushes it to the queue} otherwise
732      *
733      * @return Returns true if the message was successfully ran or placed in to the
734      *         message queue.  Returns false on failure, usually because the
735      *         looper processing the message queue is exiting.
736      * @hide
737      */
executeOrSendMessage(@onNull Message msg)738     public final boolean executeOrSendMessage(@NonNull Message msg) {
739         if (mLooper == Looper.myLooper()) {
740             dispatchMessage(msg);
741             return true;
742         }
743         return sendMessage(msg);
744     }
745 
enqueueMessage(@onNull MessageQueue queue, @NonNull Message msg, long uptimeMillis)746     private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
747             long uptimeMillis) {
748         msg.target = this;
749         msg.workSourceUid = ThreadLocalWorkSource.getUid();
750 
751         if (mAsynchronous) {
752             msg.setAsynchronous(true);
753         }
754         return queue.enqueueMessage(msg, uptimeMillis);
755     }
756 
757     /**
758      * Remove any pending posts of messages with code 'what' that are in the
759      * message queue.
760      */
removeMessages(int what)761     public final void removeMessages(int what) {
762         mQueue.removeMessages(this, what, null);
763     }
764 
765     /**
766      * Remove any pending posts of messages with code 'what' and whose obj is
767      * 'object' that are in the message queue.  If <var>object</var> is null,
768      * all messages will be removed.
769      */
removeMessages(int what, @Nullable Object object)770     public final void removeMessages(int what, @Nullable Object object) {
771         mQueue.removeMessages(this, what, object);
772     }
773 
774     /**
775      * Remove any pending posts of callbacks and sent messages whose
776      * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
777      * all callbacks and messages will be removed.
778      */
removeCallbacksAndMessages(@ullable Object token)779     public final void removeCallbacksAndMessages(@Nullable Object token) {
780         mQueue.removeCallbacksAndMessages(this, token);
781     }
782 
783     /**
784      * Check if there are any pending posts of messages with code 'what' in
785      * the message queue.
786      */
hasMessages(int what)787     public final boolean hasMessages(int what) {
788         return mQueue.hasMessages(this, what, null);
789     }
790 
791     /**
792      * Return whether there are any messages or callbacks currently scheduled on this handler.
793      * @hide
794      */
hasMessagesOrCallbacks()795     public final boolean hasMessagesOrCallbacks() {
796         return mQueue.hasMessages(this);
797     }
798 
799     /**
800      * Check if there are any pending posts of messages with code 'what' and
801      * whose obj is 'object' in the message queue.
802      */
hasMessages(int what, @Nullable Object object)803     public final boolean hasMessages(int what, @Nullable Object object) {
804         return mQueue.hasMessages(this, what, object);
805     }
806 
807     /**
808      * Check if there are any pending posts of messages with callback r in
809      * the message queue.
810      */
hasCallbacks(@onNull Runnable r)811     public final boolean hasCallbacks(@NonNull Runnable r) {
812         return mQueue.hasMessages(this, r, null);
813     }
814 
815     // if we can get rid of this method, the handler need not remember its loop
816     // we could instead export a getMessageQueue() method...
817     @NonNull
getLooper()818     public final Looper getLooper() {
819         return mLooper;
820     }
821 
dump(@onNull Printer pw, @NonNull String prefix)822     public final void dump(@NonNull Printer pw, @NonNull String prefix) {
823         pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
824         if (mLooper == null) {
825             pw.println(prefix + "looper uninitialized");
826         } else {
827             mLooper.dump(pw, prefix + "  ");
828         }
829     }
830 
831     /**
832      * @hide
833      */
dumpMine(@onNull Printer pw, @NonNull String prefix)834     public final void dumpMine(@NonNull Printer pw, @NonNull String prefix) {
835         pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
836         if (mLooper == null) {
837             pw.println(prefix + "looper uninitialized");
838         } else {
839             mLooper.dump(pw, prefix + "  ", this);
840         }
841     }
842 
843     @Override
toString()844     public String toString() {
845         return "Handler (" + getClass().getName() + ") {"
846         + Integer.toHexString(System.identityHashCode(this))
847         + "}";
848     }
849 
850     @UnsupportedAppUsage
getIMessenger()851     final IMessenger getIMessenger() {
852         synchronized (mQueue) {
853             if (mMessenger != null) {
854                 return mMessenger;
855             }
856             mMessenger = new MessengerImpl();
857             return mMessenger;
858         }
859     }
860 
861     private final class MessengerImpl extends IMessenger.Stub {
send(Message msg)862         public void send(Message msg) {
863             msg.sendingUid = Binder.getCallingUid();
864             Handler.this.sendMessage(msg);
865         }
866     }
867 
getPostMessage(Runnable r)868     private static Message getPostMessage(Runnable r) {
869         Message m = Message.obtain();
870         m.callback = r;
871         return m;
872     }
873 
874     @UnsupportedAppUsage
getPostMessage(Runnable r, Object token)875     private static Message getPostMessage(Runnable r, Object token) {
876         Message m = Message.obtain();
877         m.obj = token;
878         m.callback = r;
879         return m;
880     }
881 
handleCallback(Message message)882     private static void handleCallback(Message message) {
883         message.callback.run();
884     }
885 
886     @UnsupportedAppUsage
887     final Looper mLooper;
888     final MessageQueue mQueue;
889     @UnsupportedAppUsage
890     final Callback mCallback;
891     final boolean mAsynchronous;
892     @UnsupportedAppUsage
893     IMessenger mMessenger;
894 
895     private static final class BlockingRunnable implements Runnable {
896         private final Runnable mTask;
897         private boolean mDone;
898 
BlockingRunnable(Runnable task)899         public BlockingRunnable(Runnable task) {
900             mTask = task;
901         }
902 
903         @Override
run()904         public void run() {
905             try {
906                 mTask.run();
907             } finally {
908                 synchronized (this) {
909                     mDone = true;
910                     notifyAll();
911                 }
912             }
913         }
914 
postAndWait(Handler handler, long timeout)915         public boolean postAndWait(Handler handler, long timeout) {
916             if (!handler.post(this)) {
917                 return false;
918             }
919 
920             synchronized (this) {
921                 if (timeout > 0) {
922                     final long expirationTime = SystemClock.uptimeMillis() + timeout;
923                     while (!mDone) {
924                         long delay = expirationTime - SystemClock.uptimeMillis();
925                         if (delay <= 0) {
926                             return false; // timeout
927                         }
928                         try {
929                             wait(delay);
930                         } catch (InterruptedException ex) {
931                         }
932                     }
933                 } else {
934                     while (!mDone) {
935                         try {
936                             wait();
937                         } catch (InterruptedException ex) {
938                         }
939                     }
940                 }
941             }
942             return true;
943         }
944     }
945 }
946