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