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 than 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 new {@link android.os.Message Message} from the global message pool. More efficient than 173 * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this). 174 * If you don't want that facility, just call Message.obtain() instead. 175 */ obtainMessage()176 public final Message obtainMessage() 177 { 178 return Message.obtain(this); 179 } 180 181 /** 182 * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message. 183 * 184 * @param what Value to assign to the returned Message.what field. 185 * @return A Message from the global message pool. 186 */ obtainMessage(int what)187 public final Message obtainMessage(int what) 188 { 189 return Message.obtain(this, what); 190 } 191 192 /** 193 * 194 * Same as {@link #obtainMessage()}, except that it also sets the what and obj members 195 * of the returned Message. 196 * 197 * @param what Value to assign to the returned Message.what field. 198 * @param obj Value to assign to the returned Message.obj field. 199 * @return A Message from the global message pool. 200 */ obtainMessage(int what, Object obj)201 public final Message obtainMessage(int what, Object obj) 202 { 203 return Message.obtain(this, what, obj); 204 } 205 206 /** 207 * 208 * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned 209 * Message. 210 * @param what Value to assign to the returned Message.what field. 211 * @param arg1 Value to assign to the returned Message.arg1 field. 212 * @param arg2 Value to assign to the returned Message.arg2 field. 213 * @return A Message from the global message pool. 214 */ obtainMessage(int what, int arg1, int arg2)215 public final Message obtainMessage(int what, int arg1, int arg2) 216 { 217 return Message.obtain(this, what, arg1, arg2); 218 } 219 220 /** 221 * 222 * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the 223 * returned Message. 224 * @param what Value to assign to the returned Message.what field. 225 * @param arg1 Value to assign to the returned Message.arg1 field. 226 * @param arg2 Value to assign to the returned Message.arg2 field. 227 * @param obj Value to assign to the returned Message.obj field. 228 * @return A Message from the global message pool. 229 */ obtainMessage(int what, int arg1, int arg2, Object obj)230 public final Message obtainMessage(int what, int arg1, int arg2, Object obj) 231 { 232 return Message.obtain(this, what, arg1, arg2, obj); 233 } 234 235 /** 236 * Causes the Runnable r to be added to the message queue. 237 * The runnable will be run on the thread to which this handler is 238 * attached. 239 * 240 * @param r The Runnable that will be executed. 241 * 242 * @return Returns true if the Runnable was successfully placed in to the 243 * message queue. Returns false on failure, usually because the 244 * looper processing the message queue is exiting. 245 */ post(Runnable r)246 public final boolean post(Runnable r) 247 { 248 return sendMessageDelayed(getPostMessage(r), 0); 249 } 250 251 /** 252 * Causes the Runnable r to be added to the message queue, to be run 253 * at a specific time given by <var>uptimeMillis</var>. 254 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 255 * The runnable will be run on the thread to which this handler is attached. 256 * 257 * @param r The Runnable that will be executed. 258 * @param uptimeMillis The absolute time at which the callback should run, 259 * using the {@link android.os.SystemClock#uptimeMillis} time-base. 260 * 261 * @return Returns true if the Runnable was successfully placed in to the 262 * message queue. Returns false on failure, usually because the 263 * looper processing the message queue is exiting. Note that a 264 * result of true does not mean the Runnable will be processed -- if 265 * the looper is quit before the delivery time of the message 266 * occurs then the message will be dropped. 267 */ postAtTime(Runnable r, long uptimeMillis)268 public final boolean postAtTime(Runnable r, long uptimeMillis) 269 { 270 return sendMessageAtTime(getPostMessage(r), uptimeMillis); 271 } 272 273 /** 274 * Causes the Runnable r to be added to the message queue, to be run 275 * at a specific time given by <var>uptimeMillis</var>. 276 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 277 * The runnable will be run on the thread to which this handler is attached. 278 * 279 * @param r The Runnable that will be executed. 280 * @param uptimeMillis The absolute time at which the callback should run, 281 * using the {@link android.os.SystemClock#uptimeMillis} time-base. 282 * 283 * @return Returns true if the Runnable was successfully placed in to the 284 * message queue. Returns false on failure, usually because the 285 * looper processing the message queue is exiting. Note that a 286 * result of true does not mean the Runnable will be processed -- if 287 * the looper is quit before the delivery time of the message 288 * occurs then the message will be dropped. 289 * 290 * @see android.os.SystemClock#uptimeMillis 291 */ postAtTime(Runnable r, Object token, long uptimeMillis)292 public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) 293 { 294 return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); 295 } 296 297 /** 298 * Causes the Runnable r to be added to the message queue, to be run 299 * after the specified amount of time elapses. 300 * The runnable will be run on the thread to which this handler 301 * is attached. 302 * 303 * @param r The Runnable that will be executed. 304 * @param delayMillis The delay (in milliseconds) until the Runnable 305 * will be executed. 306 * 307 * @return Returns true if the Runnable was successfully placed in to the 308 * message queue. Returns false on failure, usually because the 309 * looper processing the message queue is exiting. Note that a 310 * result of true does not mean the Runnable will be processed -- 311 * if the looper is quit before the delivery time of the message 312 * occurs then the message will be dropped. 313 */ postDelayed(Runnable r, long delayMillis)314 public final boolean postDelayed(Runnable r, long delayMillis) 315 { 316 return sendMessageDelayed(getPostMessage(r), delayMillis); 317 } 318 319 /** 320 * Posts a message to an object that implements Runnable. 321 * Causes the Runnable r to executed on the next iteration through the 322 * message queue. The runnable will be run on the thread to which this 323 * handler is attached. 324 * <b>This method is only for use in very special circumstances -- it 325 * can easily starve the message queue, cause ordering problems, or have 326 * other unexpected side-effects.</b> 327 * 328 * @param r The Runnable that will be executed. 329 * 330 * @return Returns true if the message was successfully placed in to the 331 * message queue. Returns false on failure, usually because the 332 * looper processing the message queue is exiting. 333 */ postAtFrontOfQueue(Runnable r)334 public final boolean postAtFrontOfQueue(Runnable r) 335 { 336 return sendMessageAtFrontOfQueue(getPostMessage(r)); 337 } 338 339 /** 340 * Remove any pending posts of Runnable r that are in the message queue. 341 */ removeCallbacks(Runnable r)342 public final void removeCallbacks(Runnable r) 343 { 344 mQueue.removeMessages(this, r, null); 345 } 346 347 /** 348 * Remove any pending posts of Runnable <var>r</var> with Object 349 * <var>token</var> that are in the message queue. 350 */ removeCallbacks(Runnable r, Object token)351 public final void removeCallbacks(Runnable r, Object token) 352 { 353 mQueue.removeMessages(this, r, token); 354 } 355 356 /** 357 * Pushes a message onto the end of the message queue after all pending messages 358 * before the current time. It will be received in {@link #handleMessage}, 359 * in the thread attached to this handler. 360 * 361 * @return Returns true if the message was successfully placed in to the 362 * message queue. Returns false on failure, usually because the 363 * looper processing the message queue is exiting. 364 */ sendMessage(Message msg)365 public final boolean sendMessage(Message msg) 366 { 367 return sendMessageDelayed(msg, 0); 368 } 369 370 /** 371 * Sends a Message containing only the what value. 372 * 373 * @return Returns true if the message was successfully placed in to the 374 * message queue. Returns false on failure, usually because the 375 * looper processing the message queue is exiting. 376 */ sendEmptyMessage(int what)377 public final boolean sendEmptyMessage(int what) 378 { 379 return sendEmptyMessageDelayed(what, 0); 380 } 381 382 /** 383 * Sends a Message containing only the what value, to be delivered 384 * after the specified amount of time elapses. 385 * @see #sendMessageDelayed(android.os.Message, long) 386 * 387 * @return Returns true if the message was successfully placed in to the 388 * message queue. Returns false on failure, usually because the 389 * looper processing the message queue is exiting. 390 */ sendEmptyMessageDelayed(int what, long delayMillis)391 public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { 392 Message msg = Message.obtain(); 393 msg.what = what; 394 return sendMessageDelayed(msg, delayMillis); 395 } 396 397 /** 398 * Sends a Message containing only the what value, to be delivered 399 * at a specific time. 400 * @see #sendMessageAtTime(android.os.Message, long) 401 * 402 * @return Returns true if the message was successfully placed in to the 403 * message queue. Returns false on failure, usually because the 404 * looper processing the message queue is exiting. 405 */ 406 sendEmptyMessageAtTime(int what, long uptimeMillis)407 public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { 408 Message msg = Message.obtain(); 409 msg.what = what; 410 return sendMessageAtTime(msg, uptimeMillis); 411 } 412 413 /** 414 * Enqueue a message into the message queue after all pending messages 415 * before (current time + delayMillis). You will receive it in 416 * {@link #handleMessage}, in the thread attached to this handler. 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. Note that a 421 * result of true does not mean the message will be processed -- if 422 * the looper is quit before the delivery time of the message 423 * occurs then the message will be dropped. 424 */ sendMessageDelayed(Message msg, long delayMillis)425 public final boolean sendMessageDelayed(Message msg, long delayMillis) 426 { 427 if (delayMillis < 0) { 428 delayMillis = 0; 429 } 430 return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); 431 } 432 433 /** 434 * Enqueue a message into the message queue after all pending messages 435 * before the absolute time (in milliseconds) <var>uptimeMillis</var>. 436 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> 437 * You will receive it in {@link #handleMessage}, in the thread attached 438 * to this handler. 439 * 440 * @param uptimeMillis The absolute time at which the message should be 441 * delivered, using the 442 * {@link android.os.SystemClock#uptimeMillis} time-base. 443 * 444 * @return Returns true if the message was successfully placed in to the 445 * message queue. Returns false on failure, usually because the 446 * looper processing the message queue is exiting. Note that a 447 * result of true does not mean the message will be processed -- if 448 * the looper is quit before the delivery time of the message 449 * occurs then the message will be dropped. 450 */ sendMessageAtTime(Message msg, long uptimeMillis)451 public boolean sendMessageAtTime(Message msg, long uptimeMillis) 452 { 453 boolean sent = false; 454 MessageQueue queue = mQueue; 455 if (queue != null) { 456 msg.target = this; 457 sent = queue.enqueueMessage(msg, uptimeMillis); 458 } 459 else { 460 RuntimeException e = new RuntimeException( 461 this + " sendMessageAtTime() called with no mQueue"); 462 Log.w("Looper", e.getMessage(), e); 463 } 464 return sent; 465 } 466 467 /** 468 * Enqueue a message at the front of the message queue, to be processed on 469 * the next iteration of the message loop. You will receive it in 470 * {@link #handleMessage}, in the thread attached to this handler. 471 * <b>This method is only for use in very special circumstances -- it 472 * can easily starve the message queue, cause ordering problems, or have 473 * other unexpected side-effects.</b> 474 * 475 * @return Returns true if the message was successfully placed in to the 476 * message queue. Returns false on failure, usually because the 477 * looper processing the message queue is exiting. 478 */ sendMessageAtFrontOfQueue(Message msg)479 public final boolean sendMessageAtFrontOfQueue(Message msg) 480 { 481 boolean sent = false; 482 MessageQueue queue = mQueue; 483 if (queue != null) { 484 msg.target = this; 485 sent = queue.enqueueMessage(msg, 0); 486 } 487 else { 488 RuntimeException e = new RuntimeException( 489 this + " sendMessageAtTime() called with no mQueue"); 490 Log.w("Looper", e.getMessage(), e); 491 } 492 return sent; 493 } 494 495 /** 496 * Remove any pending posts of messages with code 'what' that are in the 497 * message queue. 498 */ removeMessages(int what)499 public final void removeMessages(int what) { 500 mQueue.removeMessages(this, what, null, true); 501 } 502 503 /** 504 * Remove any pending posts of messages with code 'what' and whose obj is 505 * 'object' that are in the message queue. 506 */ removeMessages(int what, Object object)507 public final void removeMessages(int what, Object object) { 508 mQueue.removeMessages(this, what, object, true); 509 } 510 511 /** 512 * Remove any pending posts of callbacks and sent messages whose 513 * <var>obj</var> is <var>token</var>. 514 */ removeCallbacksAndMessages(Object token)515 public final void removeCallbacksAndMessages(Object token) { 516 mQueue.removeCallbacksAndMessages(this, token); 517 } 518 519 /** 520 * Check if there are any pending posts of messages with code 'what' in 521 * the message queue. 522 */ hasMessages(int what)523 public final boolean hasMessages(int what) { 524 return mQueue.removeMessages(this, what, null, false); 525 } 526 527 /** 528 * Check if there are any pending posts of messages with code 'what' and 529 * whose obj is 'object' in the message queue. 530 */ hasMessages(int what, Object object)531 public final boolean hasMessages(int what, Object object) { 532 return mQueue.removeMessages(this, what, object, false); 533 } 534 535 // if we can get rid of this method, the handler need not remember its loop 536 // we could instead export a getMessageQueue() method... getLooper()537 public final Looper getLooper() { 538 return mLooper; 539 } 540 dump(Printer pw, String prefix)541 public final void dump(Printer pw, String prefix) { 542 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis()); 543 if (mLooper == null) { 544 pw.println(prefix + "looper uninitialized"); 545 } else { 546 mLooper.dump(pw, prefix + " "); 547 } 548 } 549 550 @Override toString()551 public String toString() { 552 return "Handler{" 553 + Integer.toHexString(System.identityHashCode(this)) 554 + "}"; 555 } 556 getIMessenger()557 final IMessenger getIMessenger() { 558 synchronized (mQueue) { 559 if (mMessenger != null) { 560 return mMessenger; 561 } 562 mMessenger = new MessengerImpl(); 563 return mMessenger; 564 } 565 } 566 567 private final class MessengerImpl extends IMessenger.Stub { send(Message msg)568 public void send(Message msg) { 569 Handler.this.sendMessage(msg); 570 } 571 } 572 getPostMessage(Runnable r)573 private final Message getPostMessage(Runnable r) { 574 Message m = Message.obtain(); 575 m.callback = r; 576 return m; 577 } 578 getPostMessage(Runnable r, Object token)579 private final Message getPostMessage(Runnable r, Object token) { 580 Message m = Message.obtain(); 581 m.obj = token; 582 m.callback = r; 583 return m; 584 } 585 handleCallback(Message message)586 private final void handleCallback(Message message) { 587 message.callback.run(); 588 } 589 590 final MessageQueue mQueue; 591 final Looper mLooper; 592 final Callback mCallback; 593 IMessenger mMessenger; 594 } 595