blob: cd39d5cc6dee2b275052b382a2c2cc1ac1e9ddcc [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.os;
18
19import android.util.Log;
20import android.util.Printer;
21
22import 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
Chris Palmer42855142010-09-09 17:04:31 -070061 * your new thread. The given Runnable or Message will then be scheduled
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 * in the Handler's message queue and processed when appropriate.
63 */
64public 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 {
78 public boolean handleMessage(Message msg);
79 }
80
81 /**
82 * Subclasses must implement this to receive messages.
83 */
84 public void handleMessage(Message msg) {
85 }
86
87 /**
88 * Handle system messages here.
89 */
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 */
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 */
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 */
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 */
165 public Handler(Looper looper, Callback callback) {
166 mLooper = looper;
167 mQueue = looper.mQueue;
168 mCallback = callback;
169 }
170
171 /**
Romain Guyf9284692011-07-13 18:46:21 -0700172 * 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 */
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 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 * 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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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.
365 */
366 public final void removeCallbacks(Runnable r, Object token)
367 {
368 mQueue.removeMessages(this, r, token);
369 }
370
371 /**
372 * Pushes a message onto the end of the message queue after all pending messages
373 * before the current time. It will be received in {@link #handleMessage},
374 * in the thread attached to this handler.
375 *
376 * @return Returns true if the message was successfully placed in to the
377 * message queue. Returns false on failure, usually because the
378 * looper processing the message queue is exiting.
379 */
380 public final boolean sendMessage(Message msg)
381 {
382 return sendMessageDelayed(msg, 0);
383 }
384
385 /**
386 * Sends a Message containing only the what value.
387 *
388 * @return Returns true if the message was successfully placed in to the
389 * message queue. Returns false on failure, usually because the
390 * looper processing the message queue is exiting.
391 */
392 public final boolean sendEmptyMessage(int what)
393 {
394 return sendEmptyMessageDelayed(what, 0);
395 }
396
397 /**
398 * Sends a Message containing only the what value, to be delivered
399 * after the specified amount of time elapses.
400 * @see #sendMessageDelayed(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 public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
407 Message msg = Message.obtain();
408 msg.what = what;
409 return sendMessageDelayed(msg, delayMillis);
410 }
411
412 /**
413 * Sends a Message containing only the what value, to be delivered
414 * at a specific time.
415 * @see #sendMessageAtTime(android.os.Message, long)
416 *
417 * @return Returns true if the message was successfully placed in to the
418 * message queue. Returns false on failure, usually because the
419 * looper processing the message queue is exiting.
420 */
421
422 public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
423 Message msg = Message.obtain();
424 msg.what = what;
425 return sendMessageAtTime(msg, uptimeMillis);
426 }
427
428 /**
429 * Enqueue a message into the message queue after all pending messages
430 * before (current time + delayMillis). You will receive it in
431 * {@link #handleMessage}, in the thread attached to this handler.
432 *
433 * @return Returns true if the message was successfully placed in to the
434 * message queue. Returns false on failure, usually because the
435 * looper processing the message queue is exiting. Note that a
436 * result of true does not mean the message will be processed -- if
437 * the looper is quit before the delivery time of the message
438 * occurs then the message will be dropped.
439 */
440 public final boolean sendMessageDelayed(Message msg, long delayMillis)
441 {
442 if (delayMillis < 0) {
443 delayMillis = 0;
444 }
445 return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
446 }
447
448 /**
449 * Enqueue a message into the message queue after all pending messages
450 * before the absolute time (in milliseconds) <var>uptimeMillis</var>.
451 * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
452 * You will receive it in {@link #handleMessage}, in the thread attached
453 * to this handler.
454 *
455 * @param uptimeMillis The absolute time at which the message should be
456 * delivered, using the
457 * {@link android.os.SystemClock#uptimeMillis} time-base.
458 *
459 * @return Returns true if the message was successfully placed in to the
460 * message queue. Returns false on failure, usually because the
461 * looper processing the message queue is exiting. Note that a
462 * result of true does not mean the message will be processed -- if
463 * the looper is quit before the delivery time of the message
464 * occurs then the message will be dropped.
465 */
466 public boolean sendMessageAtTime(Message msg, long uptimeMillis)
467 {
468 boolean sent = false;
469 MessageQueue queue = mQueue;
470 if (queue != null) {
471 msg.target = this;
472 sent = queue.enqueueMessage(msg, uptimeMillis);
473 }
474 else {
475 RuntimeException e = new RuntimeException(
476 this + " sendMessageAtTime() called with no mQueue");
477 Log.w("Looper", e.getMessage(), e);
478 }
479 return sent;
480 }
481
482 /**
483 * Enqueue a message at the front of the message queue, to be processed on
484 * the next iteration of the message loop. You will receive it in
485 * {@link #handleMessage}, in the thread attached to this handler.
486 * <b>This method is only for use in very special circumstances -- it
487 * can easily starve the message queue, cause ordering problems, or have
488 * other unexpected side-effects.</b>
489 *
490 * @return Returns true if the message was successfully placed in to the
491 * message queue. Returns false on failure, usually because the
492 * looper processing the message queue is exiting.
493 */
494 public final boolean sendMessageAtFrontOfQueue(Message msg)
495 {
496 boolean sent = false;
497 MessageQueue queue = mQueue;
498 if (queue != null) {
499 msg.target = this;
500 sent = queue.enqueueMessage(msg, 0);
501 }
502 else {
503 RuntimeException e = new RuntimeException(
504 this + " sendMessageAtTime() called with no mQueue");
505 Log.w("Looper", e.getMessage(), e);
506 }
507 return sent;
508 }
509
510 /**
511 * Remove any pending posts of messages with code 'what' that are in the
512 * message queue.
513 */
514 public final void removeMessages(int what) {
515 mQueue.removeMessages(this, what, null, true);
516 }
517
518 /**
519 * Remove any pending posts of messages with code 'what' and whose obj is
520 * 'object' that are in the message queue.
521 */
522 public final void removeMessages(int what, Object object) {
523 mQueue.removeMessages(this, what, object, true);
524 }
525
526 /**
527 * Remove any pending posts of callbacks and sent messages whose
528 * <var>obj</var> is <var>token</var>.
529 */
530 public final void removeCallbacksAndMessages(Object token) {
531 mQueue.removeCallbacksAndMessages(this, token);
532 }
533
534 /**
535 * Check if there are any pending posts of messages with code 'what' in
536 * the message queue.
537 */
538 public final boolean hasMessages(int what) {
539 return mQueue.removeMessages(this, what, null, false);
540 }
541
542 /**
543 * Check if there are any pending posts of messages with code 'what' and
544 * whose obj is 'object' in the message queue.
545 */
546 public final boolean hasMessages(int what, Object object) {
547 return mQueue.removeMessages(this, what, object, false);
548 }
549
550 // if we can get rid of this method, the handler need not remember its loop
551 // we could instead export a getMessageQueue() method...
552 public final Looper getLooper() {
553 return mLooper;
554 }
555
556 public final void dump(Printer pw, String prefix) {
557 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
558 if (mLooper == null) {
559 pw.println(prefix + "looper uninitialized");
560 } else {
561 mLooper.dump(pw, prefix + " ");
562 }
563 }
564
565 @Override
566 public String toString() {
567 return "Handler{"
568 + Integer.toHexString(System.identityHashCode(this))
569 + "}";
570 }
571
572 final IMessenger getIMessenger() {
573 synchronized (mQueue) {
574 if (mMessenger != null) {
575 return mMessenger;
576 }
577 mMessenger = new MessengerImpl();
578 return mMessenger;
579 }
580 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 private final class MessengerImpl extends IMessenger.Stub {
583 public void send(Message msg) {
584 Handler.this.sendMessage(msg);
585 }
586 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588 private final Message getPostMessage(Runnable r) {
589 Message m = Message.obtain();
590 m.callback = r;
591 return m;
592 }
593
594 private final Message getPostMessage(Runnable r, Object token) {
595 Message m = Message.obtain();
596 m.obj = token;
597 m.callback = r;
598 return m;
599 }
600
601 private final void handleCallback(Message message) {
602 message.callback.run();
603 }
604
605 final MessageQueue mQueue;
606 final Looper mLooper;
607 final Callback mCallback;
608 IMessenger mMessenger;
609}