• 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 @android.ravenwood.annotation.RavenwoodKeepWholeClass
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      *
118      * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
119      *   where operations are silently lost (if the Handler is not expecting new tasks and quits),
120      *   crashes (if a handler is sometimes created on a thread without a Looper active), or race
121      *   conditions, where the thread a handler is associated with is not what the author
122      *   anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper
123      *   explicitly, using {@link Looper#getMainLooper}, {@link android.view.View#getHandler}, or
124      *   similar. If the implicit thread local behavior is required for compatibility, use
125      *   {@code new Handler(Looper.myLooper())} to make it clear to readers.
126      *
127      */
128     @Deprecated
Handler()129     public Handler() {
130         this(null, false);
131     }
132 
133     /**
134      * Constructor associates this handler with the {@link Looper} for the
135      * current thread and takes a callback interface in which you can handle
136      * messages.
137      *
138      * If this thread does not have a looper, this handler won't be able to receive messages
139      * so an exception is thrown.
140      *
141      * @param callback The callback interface in which to handle messages, or null.
142      *
143      * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
144      *   where operations are silently lost (if the Handler is not expecting new tasks and quits),
145      *   crashes (if a handler is sometimes created on a thread without a Looper active), or race
146      *   conditions, where the thread a handler is associated with is not what the author
147      *   anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper
148      *   explicitly, using {@link Looper#getMainLooper}, {@link android.view.View#getHandler}, or
149      *   similar. If the implicit thread local behavior is required for compatibility, use
150      *   {@code new Handler(Looper.myLooper(), callback)} to make it clear to readers.
151      */
152     @Deprecated
Handler(@ullable Callback callback)153     public Handler(@Nullable Callback callback) {
154         this(callback, false);
155     }
156 
157     /**
158      * Use the provided {@link Looper} instead of the default one.
159      *
160      * @param looper The looper, must not be null.
161      */
Handler(@onNull Looper looper)162     public Handler(@NonNull Looper looper) {
163         this(looper, null, false);
164     }
165 
166     /**
167      * Use the provided {@link Looper} instead of the default one and take a callback
168      * interface in which to handle messages.
169      *
170      * @param looper The looper, must not be null.
171      * @param callback The callback interface in which to handle messages, or null.
172      */
Handler(@onNull Looper looper, @Nullable Callback callback)173     public Handler(@NonNull Looper looper, @Nullable Callback callback) {
174         this(looper, callback, false);
175     }
176 
177     /**
178      * Use the {@link Looper} for the current thread
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#postSyncBarrier()}.
187      *
188      * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
189      * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
190      *
191      * @hide
192      */
193     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Handler(boolean async)194     public Handler(boolean async) {
195         this(null, async);
196     }
197 
198     /**
199      * Use the {@link Looper} for the current thread with the specified callback interface
200      * and set whether the handler should be asynchronous.
201      *
202      * Handlers are synchronous by default unless this constructor is used to make
203      * one that is strictly asynchronous.
204      *
205      * Asynchronous messages represent interrupts or events that do not require global ordering
206      * with respect to synchronous messages.  Asynchronous messages are not subject to
207      * the synchronization barriers introduced by {@link MessageQueue#postSyncBarrier()}.
208      *
209      * @param callback The callback interface in which to handle messages, or null.
210      * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
211      * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
212      *
213      * @hide
214      */
Handler(@ullable Callback callback, boolean async)215     public Handler(@Nullable Callback callback, boolean async) {
216         if (FIND_POTENTIAL_LEAKS) {
217             final Class<? extends Handler> klass = getClass();
218             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
219                     (klass.getModifiers() & Modifier.STATIC) == 0) {
220                 Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
221                     klass.getCanonicalName());
222             }
223         }
224 
225         mLooper = Looper.myLooper();
226         if (mLooper == null) {
227             throw new RuntimeException(
228                 "Can't create handler inside thread " + Thread.currentThread()
229                         + " that has not called Looper.prepare()");
230         }
231         mQueue = mLooper.mQueue;
232         mCallback = callback;
233         mAsynchronous = async;
234         mIsShared = false;
235     }
236 
237     /**
238      * Use the provided {@link Looper} instead of the default one and take a callback
239      * interface in which to handle messages.  Also set whether the handler
240      * should be asynchronous.
241      *
242      * Handlers are synchronous by default unless this constructor is used to make
243      * one that is strictly asynchronous.
244      *
245      * Asynchronous messages represent interrupts or events that do not require global ordering
246      * with respect to synchronous messages.  Asynchronous messages are not subject to
247      * the synchronization barriers introduced by conditions such as display vsync.
248      *
249      * @param looper The looper, must not be null.
250      * @param callback The callback interface in which to handle messages, or null.
251      * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
252      * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
253      *
254      * @hide
255      */
256     @UnsupportedAppUsage
Handler(@onNull Looper looper, @Nullable Callback callback, boolean async)257     public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
258         this(looper, callback, async, /* shared= */ false);
259     }
260 
261     /** @hide */
Handler(@onNull Looper looper, @Nullable Callback callback, boolean async, boolean shared)262     public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async,
263             boolean shared) {
264         mLooper = looper;
265         mQueue = looper.mQueue;
266         mCallback = callback;
267         mAsynchronous = async;
268         mIsShared = shared;
269     }
270 
271     /**
272      * Create a new Handler whose posted messages and runnables are not subject to
273      * synchronization barriers such as display vsync.
274      *
275      * <p>Messages sent to an async handler are guaranteed to be ordered with respect to one another,
276      * but not necessarily with respect to messages from other Handlers.</p>
277      *
278      * @see #createAsync(Looper, Callback) to create an async Handler with custom message handling.
279      *
280      * @param looper the Looper that the new Handler should be bound to
281      * @return a new async Handler instance
282      */
283     @NonNull
createAsync(@onNull Looper looper)284     public static Handler createAsync(@NonNull Looper looper) {
285         if (looper == null) throw new NullPointerException("looper must not be null");
286         return new Handler(looper, null, true);
287     }
288 
289     /**
290      * Create a new Handler whose posted messages and runnables are not subject to
291      * synchronization barriers such as display vsync.
292      *
293      * <p>Messages sent to an async handler are guaranteed to be ordered with respect to one another,
294      * but not necessarily with respect to messages from other Handlers.</p>
295      *
296      * @see #createAsync(Looper) to create an async Handler without custom message handling.
297      *
298      * @param looper the Looper that the new Handler should be bound to
299      * @return a new async Handler instance
300      */
301     @NonNull
createAsync(@onNull Looper looper, @NonNull Callback callback)302     public static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) {
303         if (looper == null) throw new NullPointerException("looper must not be null");
304         if (callback == null) throw new NullPointerException("callback must not be null");
305         return new Handler(looper, callback, true);
306     }
307 
308     /** @hide */
309     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
310     @NonNull
getMain()311     public static Handler getMain() {
312         if (MAIN_THREAD_HANDLER == null) {
313             MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper());
314         }
315         return MAIN_THREAD_HANDLER;
316     }
317 
318     /** @hide */
319     @NonNull
mainIfNull(@ullable Handler handler)320     public static Handler mainIfNull(@Nullable Handler handler) {
321         return handler == null ? getMain() : handler;
322     }
323 
324     /** {@hide} */
325     @NonNull
getTraceName(@onNull Message message)326     public String getTraceName(@NonNull Message message) {
327         if (message.callback instanceof TraceNameSupplier) {
328             return ((TraceNameSupplier) message.callback).getTraceName();
329         }
330 
331         final StringBuilder sb = new StringBuilder();
332         sb.append(getClass().getName()).append(": ");
333         if (message.callback != null) {
334             sb.append(message.callback.getClass().getName());
335         } else {
336             sb.append("#").append(message.what);
337         }
338         return sb.toString();
339     }
340 
341     /**
342      * Returns a string representing the name of the specified message.
343      * The default implementation will either return the class name of the
344      * message callback if any, or the hexadecimal representation of the
345      * message "what" field.
346      *
347      * @param message The message whose name is being queried
348      */
349     @NonNull
getMessageName(@onNull Message message)350     public String getMessageName(@NonNull Message message) {
351         if (message.callback != null) {
352             return message.callback.getClass().getName();
353         }
354         return "0x" + Integer.toHexString(message.what);
355     }
356 
357     /**
358      * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
359      * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
360      *  If you don't want that facility, just call Message.obtain() instead.
361      */
362     @NonNull
obtainMessage()363     public final Message obtainMessage()
364     {
365         return Message.obtain(this);
366     }
367 
368     /**
369      * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message.
370      *
371      * @param what Value to assign to the returned Message.what field.
372      * @return A Message from the global message pool.
373      */
374     @NonNull
obtainMessage(int what)375     public final Message obtainMessage(int what)
376     {
377         return Message.obtain(this, what);
378     }
379 
380     /**
381      *
382      * Same as {@link #obtainMessage()}, except that it also sets the what and obj members
383      * of the returned Message.
384      *
385      * @param what Value to assign to the returned Message.what field.
386      * @param obj Value to assign to the returned Message.obj field.
387      * @return A Message from the global message pool.
388      */
389     @NonNull
obtainMessage(int what, @Nullable Object obj)390     public final Message obtainMessage(int what, @Nullable Object obj) {
391         return Message.obtain(this, what, obj);
392     }
393 
394     /**
395      *
396      * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned
397      * Message.
398      * @param what Value to assign to the returned Message.what field.
399      * @param arg1 Value to assign to the returned Message.arg1 field.
400      * @param arg2 Value to assign to the returned Message.arg2 field.
401      * @return A Message from the global message pool.
402      */
403     @NonNull
obtainMessage(int what, int arg1, int arg2)404     public final Message obtainMessage(int what, int arg1, int arg2)
405     {
406         return Message.obtain(this, what, arg1, arg2);
407     }
408 
409     /**
410      *
411      * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the
412      * returned Message.
413      * @param what Value to assign to the returned Message.what field.
414      * @param arg1 Value to assign to the returned Message.arg1 field.
415      * @param arg2 Value to assign to the returned Message.arg2 field.
416      * @param obj Value to assign to the returned Message.obj field.
417      * @return A Message from the global message pool.
418      */
419     @NonNull
obtainMessage(int what, int arg1, int arg2, @Nullable Object obj)420     public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
421         return Message.obtain(this, what, arg1, arg2, obj);
422     }
423 
424     /**
425      * Causes the Runnable r to be added to the message queue.
426      * The runnable will be run on the thread to which this handler is
427      * attached.
428      *
429      * @param r The Runnable that will be executed.
430      *
431      * @return Returns true if the Runnable was successfully placed in to the
432      *         message queue.  Returns false on failure, usually because the
433      *         looper processing the message queue is exiting.
434      */
post(@onNull Runnable r)435     public final boolean post(@NonNull Runnable r) {
436        return  sendMessageDelayed(getPostMessage(r), 0);
437     }
438 
439     /**
440      * Causes the Runnable r to be added to the message queue, to be run
441      * at a specific time given by <var>uptimeMillis</var>.
442      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
443      * Time spent in deep sleep will add an additional delay to execution.
444      * The runnable will be run on the thread to which this handler is attached.
445      *
446      * @param r The Runnable that will be executed.
447      * @param uptimeMillis The absolute time at which the callback should run,
448      *         using the {@link android.os.SystemClock#uptimeMillis} time-base.
449      *
450      * @return Returns true if the Runnable was successfully placed in to the
451      *         message queue.  Returns false on failure, usually because the
452      *         looper processing the message queue is exiting.  Note that a
453      *         result of true does not mean the Runnable will be processed -- if
454      *         the looper is quit before the delivery time of the message
455      *         occurs then the message will be dropped.
456      */
postAtTime(@onNull Runnable r, long uptimeMillis)457     public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
458         return sendMessageAtTime(getPostMessage(r), uptimeMillis);
459     }
460 
461     /**
462      * Causes the Runnable r to be added to the message queue, to be run
463      * at a specific time given by <var>uptimeMillis</var>.
464      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
465      * Time spent in deep sleep will add an additional delay to execution.
466      * The runnable will be run on the thread to which this handler is attached.
467      *
468      * @param r The Runnable that will be executed.
469      * @param token An instance which can be used to cancel {@code r} via
470      *         {@link #removeCallbacksAndMessages}.
471      * @param uptimeMillis The absolute time at which the callback should run,
472      *         using the {@link android.os.SystemClock#uptimeMillis} time-base.
473      *
474      * @return Returns true if the Runnable was successfully placed in to the
475      *         message queue.  Returns false on failure, usually because the
476      *         looper processing the message queue is exiting.  Note that a
477      *         result of true does not mean the Runnable will be processed -- if
478      *         the looper is quit before the delivery time of the message
479      *         occurs then the message will be dropped.
480      *
481      * @see android.os.SystemClock#uptimeMillis
482      */
postAtTime( @onNull Runnable r, @Nullable Object token, long uptimeMillis)483     public final boolean postAtTime(
484             @NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
485         return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
486     }
487 
488     /**
489      * Causes the Runnable r to be added to the message queue, to be run
490      * after the specified amount of time elapses.
491      * The runnable will be run on the thread to which this handler
492      * is attached.
493      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
494      * Time spent in deep sleep will add an additional delay to execution.
495      *
496      * @param r The Runnable that will be executed.
497      * @param delayMillis The delay (in milliseconds) until the Runnable
498      *        will be executed.
499      *
500      * @return Returns true if the Runnable was successfully placed in to the
501      *         message queue.  Returns false on failure, usually because the
502      *         looper processing the message queue is exiting.  Note that a
503      *         result of true does not mean the Runnable will be processed --
504      *         if the looper is quit before the delivery time of the message
505      *         occurs then the message will be dropped.
506      */
postDelayed(@onNull Runnable r, long delayMillis)507     public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
508         return sendMessageDelayed(getPostMessage(r), delayMillis);
509     }
510 
511     /** @hide */
postDelayed(Runnable r, int what, long delayMillis)512     public final boolean postDelayed(Runnable r, int what, long delayMillis) {
513         return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
514     }
515 
516     /**
517      * Causes the Runnable r to be added to the message queue, to be run
518      * after the specified amount of time elapses.
519      * The runnable will be run on the thread to which this handler
520      * is attached.
521      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
522      * Time spent in deep sleep will add an additional delay to execution.
523      *
524      * @param r The Runnable that will be executed.
525      * @param token An instance which can be used to cancel {@code r} via
526      *         {@link #removeCallbacksAndMessages}.
527      * @param delayMillis The delay (in milliseconds) until the Runnable
528      *        will be executed.
529      *
530      * @return Returns true if the Runnable was successfully placed in to the
531      *         message queue.  Returns false on failure, usually because the
532      *         looper processing the message queue is exiting.  Note that a
533      *         result of true does not mean the Runnable will be processed --
534      *         if the looper is quit before the delivery time of the message
535      *         occurs then the message will be dropped.
536      */
postDelayed( @onNull Runnable r, @Nullable Object token, long delayMillis)537     public final boolean postDelayed(
538             @NonNull Runnable r, @Nullable Object token, long delayMillis) {
539         return sendMessageDelayed(getPostMessage(r, token), delayMillis);
540     }
541 
542     /**
543      * Posts a message to an object that implements Runnable.
544      * Causes the Runnable r to executed on the next iteration through the
545      * message queue. The runnable will be run on the thread to which this
546      * handler is attached.
547      * <b>This method is only for use in very special circumstances -- it
548      * can easily starve the message queue, cause ordering problems, or have
549      * other unexpected side-effects.</b>
550      *
551      * @param r The Runnable that will be executed.
552      *
553      * @return Returns true if the message was successfully placed in to the
554      *         message queue.  Returns false on failure, usually because the
555      *         looper processing the message queue is exiting.
556      */
postAtFrontOfQueue(@onNull Runnable r)557     public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
558         return sendMessageAtFrontOfQueue(getPostMessage(r));
559     }
560 
561     /**
562      * Runs the specified task synchronously.
563      * <p>
564      * If the current thread is the same as the handler thread, then the runnable
565      * runs immediately without being enqueued.  Otherwise, posts the runnable
566      * to the handler and waits for it to complete before returning.
567      * </p><p>
568      * This method is dangerous!  Improper use can result in deadlocks.
569      * Never call this method while any locks are held or use it in a
570      * possibly re-entrant manner.
571      * </p><p>
572      * This method is occasionally useful in situations where a background thread
573      * must synchronously await completion of a task that must run on the
574      * handler's thread.  However, this problem is often a symptom of bad design.
575      * Consider improving the design (if possible) before resorting to this method.
576      * </p><p>
577      * One example of where you might want to use this method is when you just
578      * set up a Handler thread and need to perform some initialization steps on
579      * it before continuing execution.
580      * </p><p>
581      * If timeout occurs then this method returns <code>false</code> but the runnable
582      * will remain posted on the handler and may already be in progress or
583      * complete at a later time.
584      * </p><p>
585      * When using this method, be sure to use {@link Looper#quitSafely} when
586      * quitting the looper.  Otherwise {@link #runWithScissors} may hang indefinitely.
587      * (TODO: We should fix this by making MessageQueue aware of blocking runnables.)
588      * </p>
589      *
590      * @param r The Runnable that will be executed synchronously.
591      * @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
592      *
593      * @return Returns true if the Runnable was successfully executed.
594      *         Returns false on failure, usually because the
595      *         looper processing the message queue is exiting.
596      *
597      * @hide This method is prone to abuse and should probably not be in the API.
598      * If we ever do make it part of the API, we might want to rename it to something
599      * less funny like runUnsafe().
600      */
runWithScissors(@onNull Runnable r, long timeout)601     public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
602         if (r == null) {
603             throw new IllegalArgumentException("runnable must not be null");
604         }
605         if (timeout < 0) {
606             throw new IllegalArgumentException("timeout must be non-negative");
607         }
608 
609         if (Looper.myLooper() == mLooper) {
610             r.run();
611             return true;
612         }
613 
614         BlockingRunnable br = new BlockingRunnable(r);
615         return br.postAndWait(this, timeout);
616     }
617 
618     /**
619      * Remove any pending posts of Runnable r that are in the message queue.
620      */
removeCallbacks(@onNull Runnable r)621     public final void removeCallbacks(@NonNull Runnable r) {
622         mQueue.removeMessages(this, r, null);
623     }
624 
625     /**
626      * Remove any pending posts of Runnable <var>r</var> with Object
627      * <var>token</var> that are in the message queue.  If <var>token</var> is null,
628      * all callbacks will be removed.
629      */
removeCallbacks(@onNull Runnable r, @Nullable Object token)630     public final void removeCallbacks(@NonNull Runnable r, @Nullable Object token) {
631         mQueue.removeMessages(this, r, token);
632     }
633 
634     /**
635      * Pushes a message onto the end of the message queue after all pending messages
636      * before the current time. It will be received in {@link #handleMessage},
637      * in the thread attached to this handler.
638      *
639      * @return Returns true if the message was successfully placed in to the
640      *         message queue.  Returns false on failure, usually because the
641      *         looper processing the message queue is exiting.
642      */
sendMessage(@onNull Message msg)643     public final boolean sendMessage(@NonNull Message msg) {
644         return sendMessageDelayed(msg, 0);
645     }
646 
647     /**
648      * Sends a Message containing only the what value.
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      */
sendEmptyMessage(int what)654     public final boolean sendEmptyMessage(int what)
655     {
656         return sendEmptyMessageDelayed(what, 0);
657     }
658 
659     /**
660      * Sends a Message containing only the what value, to be delivered
661      * after the specified amount of time elapses.
662      * @see #sendMessageDelayed(android.os.Message, long)
663      *
664      * @return Returns true if the message was successfully placed in to the
665      *         message queue.  Returns false on failure, usually because the
666      *         looper processing the message queue is exiting.
667      */
sendEmptyMessageDelayed(int what, long delayMillis)668     public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
669         Message msg = Message.obtain();
670         msg.what = what;
671         return sendMessageDelayed(msg, delayMillis);
672     }
673 
674     /**
675      * Sends a Message containing only the what value, to be delivered
676      * at a specific time.
677      * @see #sendMessageAtTime(android.os.Message, long)
678      *
679      * @return Returns true if the message was successfully placed in to the
680      *         message queue.  Returns false on failure, usually because the
681      *         looper processing the message queue is exiting.
682      */
683 
sendEmptyMessageAtTime(int what, long uptimeMillis)684     public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
685         Message msg = Message.obtain();
686         msg.what = what;
687         return sendMessageAtTime(msg, uptimeMillis);
688     }
689 
690     /**
691      * Enqueue a message into the message queue after all pending messages
692      * before (current time + delayMillis). You will receive it in
693      * {@link #handleMessage}, in the thread attached to this handler.
694      *
695      * @return Returns true if the message was successfully placed in to the
696      *         message queue.  Returns false on failure, usually because the
697      *         looper processing the message queue is exiting.  Note that a
698      *         result of true does not mean the message will be processed -- if
699      *         the looper is quit before the delivery time of the message
700      *         occurs then the message will be dropped.
701      */
sendMessageDelayed(@onNull Message msg, long delayMillis)702     public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
703         if (delayMillis < 0) {
704             delayMillis = 0;
705         }
706         return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
707     }
708 
709     /**
710      * Enqueue a message into the message queue after all pending messages
711      * before the absolute time (in milliseconds) <var>uptimeMillis</var>.
712      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
713      * Time spent in deep sleep will add an additional delay to execution.
714      * You will receive it in {@link #handleMessage}, in the thread attached
715      * to this handler.
716      *
717      * @param uptimeMillis The absolute time at which the message should be
718      *         delivered, using the
719      *         {@link android.os.SystemClock#uptimeMillis} time-base.
720      *
721      * @return Returns true if the message was successfully placed in to the
722      *         message queue.  Returns false on failure, usually because the
723      *         looper processing the message queue is exiting.  Note that a
724      *         result of true does not mean the message will be processed -- if
725      *         the looper is quit before the delivery time of the message
726      *         occurs then the message will be dropped.
727      */
sendMessageAtTime(@onNull Message msg, long uptimeMillis)728     public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
729         MessageQueue queue = mQueue;
730         if (queue == null) {
731             RuntimeException e = new RuntimeException(
732                     this + " sendMessageAtTime() called with no mQueue");
733             Log.w("Looper", e.getMessage(), e);
734             return false;
735         }
736         return enqueueMessage(queue, msg, uptimeMillis);
737     }
738 
739     /**
740      * Enqueue a message at the front of the message queue, to be processed on
741      * the next iteration of the message loop.  You will receive it in
742      * {@link #handleMessage}, in the thread attached to this handler.
743      * <b>This method is only for use in very special circumstances -- it
744      * can easily starve the message queue, cause ordering problems, or have
745      * other unexpected side-effects.</b>
746      *
747      * @return Returns true if the message was successfully placed in to the
748      *         message queue.  Returns false on failure, usually because the
749      *         looper processing the message queue is exiting.
750      */
sendMessageAtFrontOfQueue(@onNull Message msg)751     public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
752         MessageQueue queue = mQueue;
753         if (queue == null) {
754             RuntimeException e = new RuntimeException(
755                     this + " sendMessageAtFrontOfQueue() called with no mQueue");
756             Log.w("Looper", e.getMessage(), e);
757             return false;
758         }
759         return enqueueMessage(queue, msg, 0);
760     }
761 
762     /**
763      * Executes the message synchronously if called on the same thread this handler corresponds to,
764      * or {@link #sendMessage pushes it to the queue} otherwise
765      *
766      * @return Returns true if the message was successfully ran or placed in to the
767      *         message queue.  Returns false on failure, usually because the
768      *         looper processing the message queue is exiting.
769      * @hide
770      */
executeOrSendMessage(@onNull Message msg)771     public final boolean executeOrSendMessage(@NonNull Message msg) {
772         if (mLooper == Looper.myLooper()) {
773             dispatchMessage(msg);
774             return true;
775         }
776         return sendMessage(msg);
777     }
778 
enqueueMessage(@onNull MessageQueue queue, @NonNull Message msg, long uptimeMillis)779     private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
780             long uptimeMillis) {
781         msg.target = this;
782         msg.workSourceUid = ThreadLocalWorkSource.getUid();
783 
784         if (mAsynchronous) {
785             msg.setAsynchronous(true);
786         }
787         return queue.enqueueMessage(msg, uptimeMillis);
788     }
789 
disallowNullArgumentIfShared(@ullable Object arg)790     private Object disallowNullArgumentIfShared(@Nullable Object arg) {
791         if (mIsShared && arg == null) {
792             throw new IllegalArgumentException("Null argument disallowed for shared handler."
793                     + " Consider creating your own Handler instance.");
794         }
795         return arg;
796     }
797 
798     /**
799      * Remove any pending posts of messages with code 'what' that are in the
800      * message queue.
801      */
removeMessages(int what)802     public final void removeMessages(int what) {
803         mQueue.removeMessages(this, what, null);
804     }
805 
806     /**
807      * Remove any pending posts of messages with code 'what' and whose obj is
808      * 'object' that are in the message queue.  If <var>object</var> is null,
809      * all messages will be removed.
810      */
removeMessages(int what, @Nullable Object object)811     public final void removeMessages(int what, @Nullable Object object) {
812         mQueue.removeMessages(this, what, disallowNullArgumentIfShared(object));
813     }
814 
815     /**
816      * Remove any pending posts of messages with code 'what' and whose obj is
817      * 'object' that are in the message queue.  If <var>object</var> is null,
818      * all messages will be removed.
819      * <p>
820      * Similar to {@link #removeMessages(int, Object)} but uses object equality
821      * ({@link Object#equals(Object)}) instead of reference equality (==) in
822      * determining whether object is the message's obj'.
823      *
824      *@hide
825      */
removeEqualMessages(int what, @Nullable Object object)826     public final void removeEqualMessages(int what, @Nullable Object object) {
827         mQueue.removeEqualMessages(this, what, disallowNullArgumentIfShared(object));
828     }
829 
830     /**
831      * Remove any pending posts of callbacks and sent messages whose
832      * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
833      * all callbacks and messages will be removed.
834      */
removeCallbacksAndMessages(@ullable Object token)835     public final void removeCallbacksAndMessages(@Nullable Object token) {
836         mQueue.removeCallbacksAndMessages(this, disallowNullArgumentIfShared(token));
837     }
838 
839     /**
840      * Remove any pending posts of callbacks and sent messages whose
841      * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
842      * all callbacks and messages will be removed.
843      *
844      *@hide
845      */
removeCallbacksAndEqualMessages(@ullable Object token)846     public final void removeCallbacksAndEqualMessages(@Nullable Object token) {
847         mQueue.removeCallbacksAndEqualMessages(this, disallowNullArgumentIfShared(token));
848     }
849     /**
850      * Check if there are any pending posts of messages with code 'what' in
851      * the message queue.
852      */
hasMessages(int what)853     public final boolean hasMessages(int what) {
854         return mQueue.hasMessages(this, what, null);
855     }
856 
857     /**
858      * Return whether there are any messages or callbacks currently scheduled on this handler.
859      * @hide
860      */
hasMessagesOrCallbacks()861     public final boolean hasMessagesOrCallbacks() {
862         return mQueue.hasMessages(this);
863     }
864 
865     /**
866      * Check if there are any pending posts of messages with code 'what' and
867      * whose obj is 'object' in the message queue.
868      */
hasMessages(int what, @Nullable Object object)869     public final boolean hasMessages(int what, @Nullable Object object) {
870         return mQueue.hasMessages(this, what, object);
871     }
872 
873     /**
874      * Check if there are any pending posts of messages with code 'what' and
875      * whose obj is 'object' in the message queue.
876      *
877      *@hide
878      */
hasEqualMessages(int what, @Nullable Object object)879     public final boolean hasEqualMessages(int what, @Nullable Object object) {
880         return mQueue.hasEqualMessages(this, what, object);
881     }
882 
883     /**
884      * Check if there are any pending posts of messages with callback r in
885      * the message queue.
886      */
hasCallbacks(@onNull Runnable r)887     public final boolean hasCallbacks(@NonNull Runnable r) {
888         return mQueue.hasMessages(this, r, null);
889     }
890 
891     // if we can get rid of this method, the handler need not remember its loop
892     // we could instead export a getMessageQueue() method...
893     @NonNull
getLooper()894     public final Looper getLooper() {
895         return mLooper;
896     }
897 
dump(@onNull Printer pw, @NonNull String prefix)898     public final void dump(@NonNull Printer pw, @NonNull String prefix) {
899         pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
900         if (mLooper == null) {
901             pw.println(prefix + "looper uninitialized");
902         } else {
903             mLooper.dump(pw, prefix + "  ");
904         }
905     }
906 
907     /**
908      * @hide
909      */
dumpMine(@onNull Printer pw, @NonNull String prefix)910     public final void dumpMine(@NonNull Printer pw, @NonNull String prefix) {
911         pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
912         if (mLooper == null) {
913             pw.println(prefix + "looper uninitialized");
914         } else {
915             mLooper.dump(pw, prefix + "  ", this);
916         }
917     }
918 
919     @Override
toString()920     public String toString() {
921         return "Handler (" + getClass().getName() + ") {"
922         + Integer.toHexString(System.identityHashCode(this))
923         + "}";
924     }
925 
926     @UnsupportedAppUsage
getIMessenger()927     final IMessenger getIMessenger() {
928         synchronized (mQueue) {
929             if (mMessenger != null) {
930                 return mMessenger;
931             }
932             mMessenger = new MessengerImpl();
933             return mMessenger;
934         }
935     }
936 
937     private final class MessengerImpl extends IMessenger.Stub {
send(Message msg)938         public void send(Message msg) {
939             msg.sendingUid = Binder.getCallingUid();
940             Handler.this.sendMessage(msg);
941         }
942     }
943 
getPostMessage(Runnable r)944     private static Message getPostMessage(Runnable r) {
945         Message m = Message.obtain();
946         m.callback = r;
947         return m;
948     }
949 
950     @UnsupportedAppUsage
getPostMessage(Runnable r, Object token)951     private static Message getPostMessage(Runnable r, Object token) {
952         Message m = Message.obtain();
953         m.obj = token;
954         m.callback = r;
955         return m;
956     }
957 
handleCallback(Message message)958     private static void handleCallback(Message message) {
959         message.callback.run();
960     }
961 
962     @UnsupportedAppUsage
963     final Looper mLooper;
964     final MessageQueue mQueue;
965     @UnsupportedAppUsage
966     final Callback mCallback;
967     final boolean mAsynchronous;
968     @UnsupportedAppUsage
969     IMessenger mMessenger;
970 
971     /** If it's a shared handler, we disallow certain dangeraous operations. */
972     private final boolean mIsShared;
973 
974     private static final class BlockingRunnable implements Runnable {
975         private final Runnable mTask;
976         private boolean mDone;
977 
BlockingRunnable(Runnable task)978         public BlockingRunnable(Runnable task) {
979             mTask = task;
980         }
981 
982         @Override
run()983         public void run() {
984             try {
985                 mTask.run();
986             } finally {
987                 synchronized (this) {
988                     mDone = true;
989                     notifyAll();
990                 }
991             }
992         }
993 
postAndWait(Handler handler, long timeout)994         public boolean postAndWait(Handler handler, long timeout) {
995             if (!handler.post(this)) {
996                 return false;
997             }
998 
999             synchronized (this) {
1000                 if (timeout > 0) {
1001                     final long expirationTime = SystemClock.uptimeMillis() + timeout;
1002                     while (!mDone) {
1003                         long delay = expirationTime - SystemClock.uptimeMillis();
1004                         if (delay <= 0) {
1005                             return false; // timeout
1006                         }
1007                         try {
1008                             wait(delay);
1009                         } catch (InterruptedException ex) {
1010                         }
1011                     }
1012                 } else {
1013                     while (!mDone) {
1014                         try {
1015                             wait();
1016                         } catch (InterruptedException ex) {
1017                         }
1018                     }
1019                 }
1020             }
1021             return true;
1022         }
1023     }
1024 }
1025