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