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