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