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