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.util.Log; 20 import android.util.Printer; 21 22 import java.lang.reflect.Modifier; 23 24 /** 25 * A Handler allows you to send and process {@link Message} and Runnable 26 * objects associated with a thread's {@link MessageQueue}. Each Handler 27 * instance is associated with a single thread and that thread's message 28 * queue. When you create a new Handler, it is bound to the thread / 29 * message queue of the thread that is creating it -- from that point on, 30 * it will deliver messages and runnables to that message queue and execute 31 * them as they come out of the message queue. 32 * 33 * <p>There are two main uses for a Handler: (1) to schedule messages and 34 * runnables to be executed as some point in the future; and (2) to enqueue 35 * an action to be performed on a different thread than your own. 36 * 37 * <p>Scheduling messages is accomplished with the 38 * {@link #post}, {@link #postAtTime(Runnable, long)}, 39 * {@link #postDelayed}, {@link #sendEmptyMessage}, 40 * {@link #sendMessage}, {@link #sendMessageAtTime}, and 41 * {@link #sendMessageDelayed} methods. The <em>post</em> versions allow 42 * you to enqueue Runnable objects to be called by the message queue when 43 * they are received; the <em>sendMessage</em> versions allow you to enqueue 44 * a {@link Message} object containing a bundle of data that will be 45 * processed by the Handler's {@link #handleMessage} method (requiring that 46 * you implement a subclass of Handler). 47 * 48 * <p>When posting or sending to a Handler, you can either 49 * allow the item to be processed as soon as the message queue is ready 50 * to do so, or specify a delay before it gets processed or absolute time for 51 * it to be processed. The latter two allow you to implement timeouts, 52 * ticks, and other timing-based behavior. 53 * 54 * <p>When a 55 * process is created for your application, its main thread is dedicated to 56 * running a message queue that takes care of managing the top-level 57 * application objects (activities, broadcast receivers, etc) and any windows 58 * they create. You can create your own threads, and communicate back with 59 * the main application thread through a Handler. This is done by calling 60 * the same <em>post</em> or <em>sendMessage</em> methods as before, but from 61 * your new thread. The given Runnable or Message will then be scheduled 62 * in the Handler's message queue and processed when appropriate. 63 */ 64 public class Handler { 65 /* 66 * Set this flag to true to detect anonymous, local or member classes 67 * that extend this Handler class and that are not static. These kind 68 * of classes can potentially create leaks. 69 */ 70 private static final boolean FIND_POTENTIAL_LEAKS = false; 71 private static final String TAG = "Handler"; 72 73 /** 74 * Callback interface you can use when instantiating a Handler to avoid 75 * having to implement your own subclass of Handler. 76 */ 77 public interface Callback { handleMessage(Message msg)78 public boolean handleMessage(Message msg); 79 } 80 81 /** 82 * Subclasses must implement this to receive messages. 83 */ handleMessage(Message msg)84 public void handleMessage(Message msg) { 85 } 86 87 /** 88 * Handle system messages here. 89 */ dispatchMessage(Message msg)90 public void dispatchMessage(Message msg) { 91 if (msg.callback != null) { 92 handleCallback(msg); 93 } else { 94 if (mCallback != null) { 95 if (mCallback.handleMessage(msg)) { 96 return; 97 } 98 } 99 handleMessage(msg); 100 } 101 } 102 103 /** 104 * Default constructor associates this handler with the queue for the 105 * current thread. 106 * 107 * If there isn't one, this handler won't be able to receive messages. 108 */ Handler()109 public Handler() { 110 if (FIND_POTENTIAL_LEAKS) { 111 final Class<? extends Handler> klass = getClass(); 112 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && 113 (klass.getModifiers() & Modifier.STATIC) == 0) { 114 Log.w(TAG, "The following Handler class should be static or leaks might occur: " + 115 klass.getCanonicalName()); 116 } 117 } 118 119 mLooper = Looper.myLooper(); 120 if (mLooper == null) { 121 throw new RuntimeException( 122 "Can't create handler inside thread that has not called Looper.prepare()"); 123 } 124 mQueue = mLooper.mQueue; 125 mCallback = null; 126 } 127 128 /** 129 * Constructor associates this handler with the queue for the 130 * current thread and takes a callback interface in which you can handle 131 * messages. 132 */ Handler(Callback callback)133 public Handler(Callback callback) { 134 if (FIND_POTENTIAL_LEAKS) { 135 final Class<? extends Handler> klass = getClass(); 136 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && 137 (klass.getModifiers() & Modifier.STATIC) == 0) { 138 Log.w(TAG, "The following Handler class should be static or leaks might occur: " + 139 klass.getCanonicalName()); 140 } 141 } 142 143 mLooper = Looper.myLooper(); 144 if (mLooper == null) { 145 throw new RuntimeException( 146 "Can't create handler inside thread that has not called Looper.prepare()"); 147 } 148 mQueue = mLooper.mQueue; 149 mCallback = callback; 150 } 151 152 /** 153 * Use the provided queue instead of the default one. 154 */ Handler(Looper looper)155 public Handler(Looper looper) { 156 mLooper = looper; 157 mQueue = looper.mQueue; 158 mCallback = null; 159 } 160 161 /** 162 * Use the provided queue instead of the default one and take a callback 163 * interface in which to handle messages. 164 */ Handler(Looper looper, Callback callback)165 public Handler(Looper looper, Callback callback) { 166 mLooper = looper; 167 mQueue = looper.mQueue; 168 mCallback = callback; 169 } 170 171 /** 172 * Returns a string representing the name of the specified message. 173 * The default implementation will either return the class name of the 174 * message callback if any, or the hexadecimal representation of the 175 * message "what" field. 176 * 177 * @param message The message whose name is being queried 178 */ getMessageName(Message message)179 public String getMessageName(Message message) { 180 if (message.callback != null) { 181 return message.callback.getClass().getName(); 182 } 183 return "0x" + Integer.toHexString(message.what); 184 } 185 186 /** 187 * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than 188 * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this). 189 * If you don't want that facility, just call Message.obtain() instead. 190 */ obtainMessage()191 public final Message obtainMessage() 192 { 193 return Message.obtain(this); 194 } 195 196 /** 197 * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message. 198 * 199 * @param what Value to assign to the returned Message.what field. 200 * @return A Message from the global message pool. 201 */ obtainMessage(int what)202 public final Message obtainMessage(int what) 203 { 204 return Message.obtain(this, what); 205 } 206 207 /** 208 * 209 * Same as {@link #obtainMessage()}, except that it also sets the what and obj members 210 * of the returned Message. 211 * 212 * @param what Value to assign to the returned Message.what field. 213 * @param obj Value to assign to the returned Message.obj field. 214 * @return A Message from the global message pool. 215 */ obtainMessage(int what, Object obj)216 public final Message obtainMessage(int what, Object obj) 217 { 218 return Message.obtain(this, what, obj); 219 } 220 221 /** 222 * 223 * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned 224 * Message. 225 * @param what Value to assign to the returned Message.what field. 226 * @param arg1 Value to assign to the returned Message.arg1 field. 227 * @param arg2 Value to assign to the returned Message.arg2 field. 228 * @return A Message from the global message pool. 229 */ obtainMessage(int what, int arg1, int arg2)230 public final Message obtainMessage(int what, int arg1, int arg2) 231 { 232 return Message.obtain(this, what, arg1, arg2); 233 } 234 235 /** 236 * 237 * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the 238 * returned Message. 239 * @param what Value to assign to the returned Message.what field. 240 * @param arg1 Value to assign to the returned Message.arg1 field. 241 * @param arg2 Value to assign to the returned Message.arg2 field. 242 * @param obj Value to assign to the returned Message.obj field. 243 * @return A Message from the global message pool. 244 */ obtainMessage(int what, int arg1, int arg2, Object obj)245 public final Message obtainMessage(int what, int arg1, int arg2, Object obj) 246 { 247 return Message.obtain(this, what, arg1, arg2, obj); 248 } 249 250 /** 251 * Causes the Runnable r to be added to the message queue. 252 * The runnable will be run on the thread to which this handler is 253 * attached. 254 * 255 * @param r The Runnable that will be executed. 256 * 257 * @return Returns true if the Runnable was successfully placed in to the 258 * message queue. Returns false on failure, usually because the 259 * looper processing the message queue is exiting. 260 */ post(Runnable r)261 public final boolean post(Runnable r) 262 { 263 return sendMessageDelayed(getPostMessage(r), 0); 264 } 265 266 /** 267 * Causes the Runnable r to be added to the message queue, to be run 268 * at a specific time given by <var>uptimeMillis</var>. 269 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 270 * The runnable will be run on the thread to which this handler is attached. 271 * 272 * @param r The Runnable that will be executed. 273 * @param uptimeMillis The absolute time at which the callback should run, 274 * using the {@link android.os.SystemClock#uptimeMillis} time-base. 275 * 276 * @return Returns true if the Runnable was successfully placed in to the 277 * message queue. Returns false on failure, usually because the 278 * looper processing the message queue is exiting. Note that a 279 * result of true does not mean the Runnable will be processed -- if 280 * the looper is quit before the delivery time of the message 281 * occurs then the message will be dropped. 282 */ postAtTime(Runnable r, long uptimeMillis)283 public final boolean postAtTime(Runnable r, long uptimeMillis) 284 { 285 return sendMessageAtTime(getPostMessage(r), uptimeMillis); 286 } 287 288 /** 289 * Causes the Runnable r to be added to the message queue, to be run 290 * at a specific time given by <var>uptimeMillis</var>. 291 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 292 * The runnable will be run on the thread to which this handler is attached. 293 * 294 * @param r The Runnable that will be executed. 295 * @param uptimeMillis The absolute time at which the callback should run, 296 * using the {@link android.os.SystemClock#uptimeMillis} time-base. 297 * 298 * @return Returns true if the Runnable was successfully placed in to the 299 * message queue. Returns false on failure, usually because the 300 * looper processing the message queue is exiting. Note that a 301 * result of true does not mean the Runnable will be processed -- if 302 * the looper is quit before the delivery time of the message 303 * occurs then the message will be dropped. 304 * 305 * @see android.os.SystemClock#uptimeMillis 306 */ postAtTime(Runnable r, Object token, long uptimeMillis)307 public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) 308 { 309 return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); 310 } 311 312 /** 313 * Causes the Runnable r to be added to the message queue, to be run 314 * after the specified amount of time elapses. 315 * The runnable will be run on the thread to which this handler 316 * is attached. 317 * 318 * @param r The Runnable that will be executed. 319 * @param delayMillis The delay (in milliseconds) until the Runnable 320 * will be executed. 321 * 322 * @return Returns true if the Runnable was successfully placed in to the 323 * message queue. Returns false on failure, usually because the 324 * looper processing the message queue is exiting. Note that a 325 * result of true does not mean the Runnable will be processed -- 326 * if the looper is quit before the delivery time of the message 327 * occurs then the message will be dropped. 328 */ postDelayed(Runnable r, long delayMillis)329 public final boolean postDelayed(Runnable r, long delayMillis) 330 { 331 return sendMessageDelayed(getPostMessage(r), delayMillis); 332 } 333 334 /** 335 * Posts a message to an object that implements Runnable. 336 * Causes the Runnable r to executed on the next iteration through the 337 * message queue. The runnable will be run on the thread to which this 338 * handler is attached. 339 * <b>This method is only for use in very special circumstances -- it 340 * can easily starve the message queue, cause ordering problems, or have 341 * other unexpected side-effects.</b> 342 * 343 * @param r The Runnable that will be executed. 344 * 345 * @return Returns true if the message was successfully placed in to the 346 * message queue. Returns false on failure, usually because the 347 * looper processing the message queue is exiting. 348 */ postAtFrontOfQueue(Runnable r)349 public final boolean postAtFrontOfQueue(Runnable r) 350 { 351 return sendMessageAtFrontOfQueue(getPostMessage(r)); 352 } 353 354 /** 355 * Remove any pending posts of Runnable r that are in the message queue. 356 */ removeCallbacks(Runnable r)357 public final void removeCallbacks(Runnable r) 358 { 359 mQueue.removeMessages(this, r, null); 360 } 361 362 /** 363 * Remove any pending posts of Runnable <var>r</var> with Object 364 * <var>token</var> that are in the message queue. If <var>token</var> is null, 365 * all callbacks will be removed. 366 */ removeCallbacks(Runnable r, Object token)367 public final void removeCallbacks(Runnable r, Object token) 368 { 369 mQueue.removeMessages(this, r, token); 370 } 371 372 /** 373 * Pushes a message onto the end of the message queue after all pending messages 374 * before the current time. It will be received in {@link #handleMessage}, 375 * in the thread attached to this handler. 376 * 377 * @return Returns true if the message was successfully placed in to the 378 * message queue. Returns false on failure, usually because the 379 * looper processing the message queue is exiting. 380 */ sendMessage(Message msg)381 public final boolean sendMessage(Message msg) 382 { 383 return sendMessageDelayed(msg, 0); 384 } 385 386 /** 387 * Sends a Message containing only the what value. 388 * 389 * @return Returns true if the message was successfully placed in to the 390 * message queue. Returns false on failure, usually because the 391 * looper processing the message queue is exiting. 392 */ sendEmptyMessage(int what)393 public final boolean sendEmptyMessage(int what) 394 { 395 return sendEmptyMessageDelayed(what, 0); 396 } 397 398 /** 399 * Sends a Message containing only the what value, to be delivered 400 * after the specified amount of time elapses. 401 * @see #sendMessageDelayed(android.os.Message, long) 402 * 403 * @return Returns true if the message was successfully placed in to the 404 * message queue. Returns false on failure, usually because the 405 * looper processing the message queue is exiting. 406 */ sendEmptyMessageDelayed(int what, long delayMillis)407 public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { 408 Message msg = Message.obtain(); 409 msg.what = what; 410 return sendMessageDelayed(msg, delayMillis); 411 } 412 413 /** 414 * Sends a Message containing only the what value, to be delivered 415 * at a specific time. 416 * @see #sendMessageAtTime(android.os.Message, long) 417 * 418 * @return Returns true if the message was successfully placed in to the 419 * message queue. Returns false on failure, usually because the 420 * looper processing the message queue is exiting. 421 */ 422 sendEmptyMessageAtTime(int what, long uptimeMillis)423 public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { 424 Message msg = Message.obtain(); 425 msg.what = what; 426 return sendMessageAtTime(msg, uptimeMillis); 427 } 428 429 /** 430 * Enqueue a message into the message queue after all pending messages 431 * before (current time + delayMillis). You will receive it in 432 * {@link #handleMessage}, in the thread attached to this handler. 433 * 434 * @return Returns true if the message was successfully placed in to the 435 * message queue. Returns false on failure, usually because the 436 * looper processing the message queue is exiting. Note that a 437 * result of true does not mean the message will be processed -- if 438 * the looper is quit before the delivery time of the message 439 * occurs then the message will be dropped. 440 */ sendMessageDelayed(Message msg, long delayMillis)441 public final boolean sendMessageDelayed(Message msg, long delayMillis) 442 { 443 if (delayMillis < 0) { 444 delayMillis = 0; 445 } 446 return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); 447 } 448 449 /** 450 * Enqueue a message into the message queue after all pending messages 451 * before the absolute time (in milliseconds) <var>uptimeMillis</var>. 452 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 453 * You will receive it in {@link #handleMessage}, in the thread attached 454 * to this handler. 455 * 456 * @param uptimeMillis The absolute time at which the message should be 457 * delivered, using the 458 * {@link android.os.SystemClock#uptimeMillis} time-base. 459 * 460 * @return Returns true if the message was successfully placed in to the 461 * message queue. Returns false on failure, usually because the 462 * looper processing the message queue is exiting. Note that a 463 * result of true does not mean the message will be processed -- if 464 * the looper is quit before the delivery time of the message 465 * occurs then the message will be dropped. 466 */ sendMessageAtTime(Message msg, long uptimeMillis)467 public boolean sendMessageAtTime(Message msg, long uptimeMillis) 468 { 469 boolean sent = false; 470 MessageQueue queue = mQueue; 471 if (queue != null) { 472 msg.target = this; 473 sent = queue.enqueueMessage(msg, uptimeMillis); 474 } 475 else { 476 RuntimeException e = new RuntimeException( 477 this + " sendMessageAtTime() called with no mQueue"); 478 Log.w("Looper", e.getMessage(), e); 479 } 480 return sent; 481 } 482 483 /** 484 * Enqueue a message at the front of the message queue, to be processed on 485 * the next iteration of the message loop. You will receive it in 486 * {@link #handleMessage}, in the thread attached to this handler. 487 * <b>This method is only for use in very special circumstances -- it 488 * can easily starve the message queue, cause ordering problems, or have 489 * other unexpected side-effects.</b> 490 * 491 * @return Returns true if the message was successfully placed in to the 492 * message queue. Returns false on failure, usually because the 493 * looper processing the message queue is exiting. 494 */ sendMessageAtFrontOfQueue(Message msg)495 public final boolean sendMessageAtFrontOfQueue(Message msg) 496 { 497 boolean sent = false; 498 MessageQueue queue = mQueue; 499 if (queue != null) { 500 msg.target = this; 501 sent = queue.enqueueMessage(msg, 0); 502 } 503 else { 504 RuntimeException e = new RuntimeException( 505 this + " sendMessageAtTime() called with no mQueue"); 506 Log.w("Looper", e.getMessage(), e); 507 } 508 return sent; 509 } 510 511 /** 512 * Remove any pending posts of messages with code 'what' that are in the 513 * message queue. 514 */ removeMessages(int what)515 public final void removeMessages(int what) { 516 mQueue.removeMessages(this, what, null, true); 517 } 518 519 /** 520 * Remove any pending posts of messages with code 'what' and whose obj is 521 * 'object' that are in the message queue. If <var>token</var> is null, 522 * all messages will be removed. 523 */ removeMessages(int what, Object object)524 public final void removeMessages(int what, Object object) { 525 mQueue.removeMessages(this, what, object, true); 526 } 527 528 /** 529 * Remove any pending posts of callbacks and sent messages whose 530 * <var>obj</var> is <var>token</var>. If <var>token</var> is null, 531 * all callbacks and messages will be removed. 532 */ removeCallbacksAndMessages(Object token)533 public final void removeCallbacksAndMessages(Object token) { 534 mQueue.removeCallbacksAndMessages(this, token); 535 } 536 537 /** 538 * Check if there are any pending posts of messages with code 'what' in 539 * the message queue. 540 */ hasMessages(int what)541 public final boolean hasMessages(int what) { 542 return mQueue.removeMessages(this, what, null, false); 543 } 544 545 /** 546 * Check if there are any pending posts of messages with code 'what' and 547 * whose obj is 'object' in the message queue. 548 */ hasMessages(int what, Object object)549 public final boolean hasMessages(int what, Object object) { 550 return mQueue.removeMessages(this, what, object, false); 551 } 552 553 // if we can get rid of this method, the handler need not remember its loop 554 // we could instead export a getMessageQueue() method... getLooper()555 public final Looper getLooper() { 556 return mLooper; 557 } 558 dump(Printer pw, String prefix)559 public final void dump(Printer pw, String prefix) { 560 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis()); 561 if (mLooper == null) { 562 pw.println(prefix + "looper uninitialized"); 563 } else { 564 mLooper.dump(pw, prefix + " "); 565 } 566 } 567 568 @Override toString()569 public String toString() { 570 return "Handler (" + getClass().getName() + ") {" 571 + Integer.toHexString(System.identityHashCode(this)) 572 + "}"; 573 } 574 getIMessenger()575 final IMessenger getIMessenger() { 576 synchronized (mQueue) { 577 if (mMessenger != null) { 578 return mMessenger; 579 } 580 mMessenger = new MessengerImpl(); 581 return mMessenger; 582 } 583 } 584 585 private final class MessengerImpl extends IMessenger.Stub { send(Message msg)586 public void send(Message msg) { 587 Handler.this.sendMessage(msg); 588 } 589 } 590 getPostMessage(Runnable r)591 private final Message getPostMessage(Runnable r) { 592 Message m = Message.obtain(); 593 m.callback = r; 594 return m; 595 } 596 getPostMessage(Runnable r, Object token)597 private final Message getPostMessage(Runnable r, Object token) { 598 Message m = Message.obtain(); 599 m.obj = token; 600 m.callback = r; 601 return m; 602 } 603 handleCallback(Message message)604 private final void handleCallback(Message message) { 605 message.callback.run(); 606 } 607 608 final MessageQueue mQueue; 609 final Looper mLooper; 610 final Callback mCallback; 611 IMessenger mMessenger; 612 } 613