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