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