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 that has not called Looper.prepare()"); 206 } 207 mQueue = mLooper.mQueue; 208 mCallback = callback; 209 mAsynchronous = async; 210 } 211 212 /** 213 * Use the provided {@link Looper} instead of the default one and take a callback 214 * interface in which to handle messages. Also set whether the handler 215 * should be asynchronous. 216 * 217 * Handlers are synchronous by default unless this constructor is used to make 218 * one that is strictly asynchronous. 219 * 220 * Asynchronous messages represent interrupts or events that do not require global ordering 221 * with respect to synchronous messages. Asynchronous messages are not subject to 222 * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. 223 * 224 * @param looper The looper, must not be null. 225 * @param callback The callback interface in which to handle messages, or null. 226 * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for 227 * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. 228 * 229 * @hide 230 */ Handler(Looper looper, Callback callback, boolean async)231 public Handler(Looper looper, Callback callback, boolean async) { 232 mLooper = looper; 233 mQueue = looper.mQueue; 234 mCallback = callback; 235 mAsynchronous = async; 236 } 237 238 /** @hide */ 239 @NonNull getMain()240 public static Handler getMain() { 241 if (MAIN_THREAD_HANDLER == null) { 242 MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper()); 243 } 244 return MAIN_THREAD_HANDLER; 245 } 246 247 /** @hide */ 248 @NonNull mainIfNull(@ullable Handler handler)249 public static Handler mainIfNull(@Nullable Handler handler) { 250 return handler == null ? getMain() : handler; 251 } 252 253 /** {@hide} */ getTraceName(Message message)254 public String getTraceName(Message message) { 255 final StringBuilder sb = new StringBuilder(); 256 sb.append(getClass().getName()).append(": "); 257 if (message.callback != null) { 258 sb.append(message.callback.getClass().getName()); 259 } else { 260 sb.append("#").append(message.what); 261 } 262 return sb.toString(); 263 } 264 265 /** 266 * Returns a string representing the name of the specified message. 267 * The default implementation will either return the class name of the 268 * message callback if any, or the hexadecimal representation of the 269 * message "what" field. 270 * 271 * @param message The message whose name is being queried 272 */ getMessageName(Message message)273 public String getMessageName(Message message) { 274 if (message.callback != null) { 275 return message.callback.getClass().getName(); 276 } 277 return "0x" + Integer.toHexString(message.what); 278 } 279 280 /** 281 * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than 282 * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this). 283 * If you don't want that facility, just call Message.obtain() instead. 284 */ obtainMessage()285 public final Message obtainMessage() 286 { 287 return Message.obtain(this); 288 } 289 290 /** 291 * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message. 292 * 293 * @param what Value to assign to the returned Message.what field. 294 * @return A Message from the global message pool. 295 */ obtainMessage(int what)296 public final Message obtainMessage(int what) 297 { 298 return Message.obtain(this, what); 299 } 300 301 /** 302 * 303 * Same as {@link #obtainMessage()}, except that it also sets the what and obj members 304 * of the returned Message. 305 * 306 * @param what Value to assign to the returned Message.what field. 307 * @param obj Value to assign to the returned Message.obj field. 308 * @return A Message from the global message pool. 309 */ obtainMessage(int what, Object obj)310 public final Message obtainMessage(int what, Object obj) 311 { 312 return Message.obtain(this, what, obj); 313 } 314 315 /** 316 * 317 * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned 318 * Message. 319 * @param what Value to assign to the returned Message.what field. 320 * @param arg1 Value to assign to the returned Message.arg1 field. 321 * @param arg2 Value to assign to the returned Message.arg2 field. 322 * @return A Message from the global message pool. 323 */ obtainMessage(int what, int arg1, int arg2)324 public final Message obtainMessage(int what, int arg1, int arg2) 325 { 326 return Message.obtain(this, what, arg1, arg2); 327 } 328 329 /** 330 * 331 * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the 332 * returned Message. 333 * @param what Value to assign to the returned Message.what field. 334 * @param arg1 Value to assign to the returned Message.arg1 field. 335 * @param arg2 Value to assign to the returned Message.arg2 field. 336 * @param obj Value to assign to the returned Message.obj field. 337 * @return A Message from the global message pool. 338 */ obtainMessage(int what, int arg1, int arg2, Object obj)339 public final Message obtainMessage(int what, int arg1, int arg2, Object obj) 340 { 341 return Message.obtain(this, what, arg1, arg2, obj); 342 } 343 344 /** 345 * Causes the Runnable r to be added to the message queue. 346 * The runnable will be run on the thread to which this handler is 347 * attached. 348 * 349 * @param r The Runnable that will be executed. 350 * 351 * @return Returns true if the Runnable was successfully placed in to the 352 * message queue. Returns false on failure, usually because the 353 * looper processing the message queue is exiting. 354 */ post(Runnable r)355 public final boolean post(Runnable r) 356 { 357 return sendMessageDelayed(getPostMessage(r), 0); 358 } 359 360 /** 361 * Causes the Runnable r to be added to the message queue, to be run 362 * at a specific time given by <var>uptimeMillis</var>. 363 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 364 * Time spent in deep sleep will add an additional delay to execution. 365 * The runnable will be run on the thread to which this handler is attached. 366 * 367 * @param r The Runnable that will be executed. 368 * @param uptimeMillis The absolute time at which the callback should run, 369 * using the {@link android.os.SystemClock#uptimeMillis} time-base. 370 * 371 * @return Returns true if the Runnable was successfully placed in to the 372 * message queue. Returns false on failure, usually because the 373 * looper processing the message queue is exiting. Note that a 374 * result of true does not mean the Runnable will be processed -- if 375 * the looper is quit before the delivery time of the message 376 * occurs then the message will be dropped. 377 */ postAtTime(Runnable r, long uptimeMillis)378 public final boolean postAtTime(Runnable r, long uptimeMillis) 379 { 380 return sendMessageAtTime(getPostMessage(r), uptimeMillis); 381 } 382 383 /** 384 * Causes the Runnable r to be added to the message queue, to be run 385 * at a specific time given by <var>uptimeMillis</var>. 386 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 387 * Time spent in deep sleep will add an additional delay to execution. 388 * The runnable will be run on the thread to which this handler is attached. 389 * 390 * @param r The Runnable that will be executed. 391 * @param uptimeMillis The absolute time at which the callback should run, 392 * using the {@link android.os.SystemClock#uptimeMillis} time-base. 393 * 394 * @return Returns true if the Runnable was successfully placed in to the 395 * message queue. Returns false on failure, usually because the 396 * looper processing the message queue is exiting. Note that a 397 * result of true does not mean the Runnable will be processed -- if 398 * the looper is quit before the delivery time of the message 399 * occurs then the message will be dropped. 400 * 401 * @see android.os.SystemClock#uptimeMillis 402 */ postAtTime(Runnable r, Object token, long uptimeMillis)403 public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) 404 { 405 return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); 406 } 407 408 /** 409 * Causes the Runnable r to be added to the message queue, to be run 410 * after the specified amount of time elapses. 411 * The runnable will be run on the thread to which this handler 412 * is attached. 413 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 414 * Time spent in deep sleep will add an additional delay to execution. 415 * 416 * @param r The Runnable that will be executed. 417 * @param delayMillis The delay (in milliseconds) until the Runnable 418 * will be executed. 419 * 420 * @return Returns true if the Runnable was successfully placed in to the 421 * message queue. Returns false on failure, usually because the 422 * looper processing the message queue is exiting. Note that a 423 * result of true does not mean the Runnable will be processed -- 424 * if the looper is quit before the delivery time of the message 425 * occurs then the message will be dropped. 426 */ postDelayed(Runnable r, long delayMillis)427 public final boolean postDelayed(Runnable r, long delayMillis) 428 { 429 return sendMessageDelayed(getPostMessage(r), delayMillis); 430 } 431 432 /** 433 * Posts a message to an object that implements Runnable. 434 * Causes the Runnable r to executed on the next iteration through the 435 * message queue. The runnable will be run on the thread to which this 436 * handler is attached. 437 * <b>This method is only for use in very special circumstances -- it 438 * can easily starve the message queue, cause ordering problems, or have 439 * other unexpected side-effects.</b> 440 * 441 * @param r The Runnable that will be executed. 442 * 443 * @return Returns true if the message was successfully placed in to the 444 * message queue. Returns false on failure, usually because the 445 * looper processing the message queue is exiting. 446 */ postAtFrontOfQueue(Runnable r)447 public final boolean postAtFrontOfQueue(Runnable r) 448 { 449 return sendMessageAtFrontOfQueue(getPostMessage(r)); 450 } 451 452 /** 453 * Runs the specified task synchronously. 454 * <p> 455 * If the current thread is the same as the handler thread, then the runnable 456 * runs immediately without being enqueued. Otherwise, posts the runnable 457 * to the handler and waits for it to complete before returning. 458 * </p><p> 459 * This method is dangerous! Improper use can result in deadlocks. 460 * Never call this method while any locks are held or use it in a 461 * possibly re-entrant manner. 462 * </p><p> 463 * This method is occasionally useful in situations where a background thread 464 * must synchronously await completion of a task that must run on the 465 * handler's thread. However, this problem is often a symptom of bad design. 466 * Consider improving the design (if possible) before resorting to this method. 467 * </p><p> 468 * One example of where you might want to use this method is when you just 469 * set up a Handler thread and need to perform some initialization steps on 470 * it before continuing execution. 471 * </p><p> 472 * If timeout occurs then this method returns <code>false</code> but the runnable 473 * will remain posted on the handler and may already be in progress or 474 * complete at a later time. 475 * </p><p> 476 * When using this method, be sure to use {@link Looper#quitSafely} when 477 * quitting the looper. Otherwise {@link #runWithScissors} may hang indefinitely. 478 * (TODO: We should fix this by making MessageQueue aware of blocking runnables.) 479 * </p> 480 * 481 * @param r The Runnable that will be executed synchronously. 482 * @param timeout The timeout in milliseconds, or 0 to wait indefinitely. 483 * 484 * @return Returns true if the Runnable was successfully executed. 485 * Returns false on failure, usually because the 486 * looper processing the message queue is exiting. 487 * 488 * @hide This method is prone to abuse and should probably not be in the API. 489 * If we ever do make it part of the API, we might want to rename it to something 490 * less funny like runUnsafe(). 491 */ runWithScissors(final Runnable r, long timeout)492 public final boolean runWithScissors(final Runnable r, long timeout) { 493 if (r == null) { 494 throw new IllegalArgumentException("runnable must not be null"); 495 } 496 if (timeout < 0) { 497 throw new IllegalArgumentException("timeout must be non-negative"); 498 } 499 500 if (Looper.myLooper() == mLooper) { 501 r.run(); 502 return true; 503 } 504 505 BlockingRunnable br = new BlockingRunnable(r); 506 return br.postAndWait(this, timeout); 507 } 508 509 /** 510 * Remove any pending posts of Runnable r that are in the message queue. 511 */ removeCallbacks(Runnable r)512 public final void removeCallbacks(Runnable r) 513 { 514 mQueue.removeMessages(this, r, null); 515 } 516 517 /** 518 * Remove any pending posts of Runnable <var>r</var> with Object 519 * <var>token</var> that are in the message queue. If <var>token</var> is null, 520 * all callbacks will be removed. 521 */ removeCallbacks(Runnable r, Object token)522 public final void removeCallbacks(Runnable r, Object token) 523 { 524 mQueue.removeMessages(this, r, token); 525 } 526 527 /** 528 * Pushes a message onto the end of the message queue after all pending messages 529 * before the current time. It will be received in {@link #handleMessage}, 530 * in the thread attached to this handler. 531 * 532 * @return Returns true if the message was successfully placed in to the 533 * message queue. Returns false on failure, usually because the 534 * looper processing the message queue is exiting. 535 */ sendMessage(Message msg)536 public final boolean sendMessage(Message msg) 537 { 538 return sendMessageDelayed(msg, 0); 539 } 540 541 /** 542 * Sends a Message containing only the what value. 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 */ sendEmptyMessage(int what)548 public final boolean sendEmptyMessage(int what) 549 { 550 return sendEmptyMessageDelayed(what, 0); 551 } 552 553 /** 554 * Sends a Message containing only the what value, to be delivered 555 * after the specified amount of time elapses. 556 * @see #sendMessageDelayed(android.os.Message, long) 557 * 558 * @return Returns true if the message was successfully placed in to the 559 * message queue. Returns false on failure, usually because the 560 * looper processing the message queue is exiting. 561 */ sendEmptyMessageDelayed(int what, long delayMillis)562 public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { 563 Message msg = Message.obtain(); 564 msg.what = what; 565 return sendMessageDelayed(msg, delayMillis); 566 } 567 568 /** 569 * Sends a Message containing only the what value, to be delivered 570 * at a specific time. 571 * @see #sendMessageAtTime(android.os.Message, long) 572 * 573 * @return Returns true if the message was successfully placed in to the 574 * message queue. Returns false on failure, usually because the 575 * looper processing the message queue is exiting. 576 */ 577 sendEmptyMessageAtTime(int what, long uptimeMillis)578 public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { 579 Message msg = Message.obtain(); 580 msg.what = what; 581 return sendMessageAtTime(msg, uptimeMillis); 582 } 583 584 /** 585 * Enqueue a message into the message queue after all pending messages 586 * before (current time + delayMillis). You will receive it in 587 * {@link #handleMessage}, in the thread attached to this handler. 588 * 589 * @return Returns true if the message was successfully placed in to the 590 * message queue. Returns false on failure, usually because the 591 * looper processing the message queue is exiting. Note that a 592 * result of true does not mean the message will be processed -- if 593 * the looper is quit before the delivery time of the message 594 * occurs then the message will be dropped. 595 */ sendMessageDelayed(Message msg, long delayMillis)596 public final boolean sendMessageDelayed(Message msg, long delayMillis) 597 { 598 if (delayMillis < 0) { 599 delayMillis = 0; 600 } 601 return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); 602 } 603 604 /** 605 * Enqueue a message into the message queue after all pending messages 606 * before the absolute time (in milliseconds) <var>uptimeMillis</var>. 607 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 608 * Time spent in deep sleep will add an additional delay to execution. 609 * You will receive it in {@link #handleMessage}, in the thread attached 610 * to this handler. 611 * 612 * @param uptimeMillis The absolute time at which the message should be 613 * delivered, using the 614 * {@link android.os.SystemClock#uptimeMillis} time-base. 615 * 616 * @return Returns true if the message was successfully placed in to the 617 * message queue. Returns false on failure, usually because the 618 * looper processing the message queue is exiting. Note that a 619 * result of true does not mean the message will be processed -- if 620 * the looper is quit before the delivery time of the message 621 * occurs then the message will be dropped. 622 */ sendMessageAtTime(Message msg, long uptimeMillis)623 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { 624 MessageQueue queue = mQueue; 625 if (queue == null) { 626 RuntimeException e = new RuntimeException( 627 this + " sendMessageAtTime() called with no mQueue"); 628 Log.w("Looper", e.getMessage(), e); 629 return false; 630 } 631 return enqueueMessage(queue, msg, uptimeMillis); 632 } 633 634 /** 635 * Enqueue a message at the front of the message queue, to be processed on 636 * the next iteration of the message loop. You will receive it in 637 * {@link #handleMessage}, in the thread attached to this handler. 638 * <b>This method is only for use in very special circumstances -- it 639 * can easily starve the message queue, cause ordering problems, or have 640 * other unexpected side-effects.</b> 641 * 642 * @return Returns true if the message was successfully placed in to the 643 * message queue. Returns false on failure, usually because the 644 * looper processing the message queue is exiting. 645 */ sendMessageAtFrontOfQueue(Message msg)646 public final boolean sendMessageAtFrontOfQueue(Message msg) { 647 MessageQueue queue = mQueue; 648 if (queue == null) { 649 RuntimeException e = new RuntimeException( 650 this + " sendMessageAtTime() called with no mQueue"); 651 Log.w("Looper", e.getMessage(), e); 652 return false; 653 } 654 return enqueueMessage(queue, msg, 0); 655 } 656 enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis)657 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { 658 msg.target = this; 659 if (mAsynchronous) { 660 msg.setAsynchronous(true); 661 } 662 return queue.enqueueMessage(msg, uptimeMillis); 663 } 664 665 /** 666 * Remove any pending posts of messages with code 'what' that are in the 667 * message queue. 668 */ removeMessages(int what)669 public final void removeMessages(int what) { 670 mQueue.removeMessages(this, what, null); 671 } 672 673 /** 674 * Remove any pending posts of messages with code 'what' and whose obj is 675 * 'object' that are in the message queue. If <var>object</var> is null, 676 * all messages will be removed. 677 */ removeMessages(int what, Object object)678 public final void removeMessages(int what, Object object) { 679 mQueue.removeMessages(this, what, object); 680 } 681 682 /** 683 * Remove any pending posts of callbacks and sent messages whose 684 * <var>obj</var> is <var>token</var>. If <var>token</var> is null, 685 * all callbacks and messages will be removed. 686 */ removeCallbacksAndMessages(Object token)687 public final void removeCallbacksAndMessages(Object token) { 688 mQueue.removeCallbacksAndMessages(this, token); 689 } 690 691 /** 692 * Check if there are any pending posts of messages with code 'what' in 693 * the message queue. 694 */ hasMessages(int what)695 public final boolean hasMessages(int what) { 696 return mQueue.hasMessages(this, what, null); 697 } 698 699 /** 700 * Return whether there are any messages or callbacks currently scheduled on this handler. 701 * @hide 702 */ hasMessagesOrCallbacks()703 public final boolean hasMessagesOrCallbacks() { 704 return mQueue.hasMessages(this); 705 } 706 707 /** 708 * Check if there are any pending posts of messages with code 'what' and 709 * whose obj is 'object' in the message queue. 710 */ hasMessages(int what, Object object)711 public final boolean hasMessages(int what, Object object) { 712 return mQueue.hasMessages(this, what, object); 713 } 714 715 /** 716 * Check if there are any pending posts of messages with callback r in 717 * the message queue. 718 * 719 * @hide 720 */ hasCallbacks(Runnable r)721 public final boolean hasCallbacks(Runnable r) { 722 return mQueue.hasMessages(this, r, null); 723 } 724 725 // if we can get rid of this method, the handler need not remember its loop 726 // we could instead export a getMessageQueue() method... getLooper()727 public final Looper getLooper() { 728 return mLooper; 729 } 730 dump(Printer pw, String prefix)731 public final void dump(Printer pw, String prefix) { 732 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis()); 733 if (mLooper == null) { 734 pw.println(prefix + "looper uninitialized"); 735 } else { 736 mLooper.dump(pw, prefix + " "); 737 } 738 } 739 740 /** 741 * @hide 742 */ dumpMine(Printer pw, String prefix)743 public final void dumpMine(Printer pw, String prefix) { 744 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis()); 745 if (mLooper == null) { 746 pw.println(prefix + "looper uninitialized"); 747 } else { 748 mLooper.dump(pw, prefix + " ", this); 749 } 750 } 751 752 @Override toString()753 public String toString() { 754 return "Handler (" + getClass().getName() + ") {" 755 + Integer.toHexString(System.identityHashCode(this)) 756 + "}"; 757 } 758 getIMessenger()759 final IMessenger getIMessenger() { 760 synchronized (mQueue) { 761 if (mMessenger != null) { 762 return mMessenger; 763 } 764 mMessenger = new MessengerImpl(); 765 return mMessenger; 766 } 767 } 768 769 private final class MessengerImpl extends IMessenger.Stub { send(Message msg)770 public void send(Message msg) { 771 msg.sendingUid = Binder.getCallingUid(); 772 Handler.this.sendMessage(msg); 773 } 774 } 775 getPostMessage(Runnable r)776 private static Message getPostMessage(Runnable r) { 777 Message m = Message.obtain(); 778 m.callback = r; 779 return m; 780 } 781 getPostMessage(Runnable r, Object token)782 private static Message getPostMessage(Runnable r, Object token) { 783 Message m = Message.obtain(); 784 m.obj = token; 785 m.callback = r; 786 return m; 787 } 788 handleCallback(Message message)789 private static void handleCallback(Message message) { 790 message.callback.run(); 791 } 792 793 final Looper mLooper; 794 final MessageQueue mQueue; 795 final Callback mCallback; 796 final boolean mAsynchronous; 797 IMessenger mMessenger; 798 799 private static final class BlockingRunnable implements Runnable { 800 private final Runnable mTask; 801 private boolean mDone; 802 BlockingRunnable(Runnable task)803 public BlockingRunnable(Runnable task) { 804 mTask = task; 805 } 806 807 @Override run()808 public void run() { 809 try { 810 mTask.run(); 811 } finally { 812 synchronized (this) { 813 mDone = true; 814 notifyAll(); 815 } 816 } 817 } 818 postAndWait(Handler handler, long timeout)819 public boolean postAndWait(Handler handler, long timeout) { 820 if (!handler.post(this)) { 821 return false; 822 } 823 824 synchronized (this) { 825 if (timeout > 0) { 826 final long expirationTime = SystemClock.uptimeMillis() + timeout; 827 while (!mDone) { 828 long delay = expirationTime - SystemClock.uptimeMillis(); 829 if (delay <= 0) { 830 return false; // timeout 831 } 832 try { 833 wait(delay); 834 } catch (InterruptedException ex) { 835 } 836 } 837 } else { 838 while (!mDone) { 839 try { 840 wait(); 841 } catch (InterruptedException ex) { 842 } 843 } 844 } 845 } 846 return true; 847 } 848 } 849 } 850