blob: b892c8128cddf6a0aa0f7d51fa535533fc63974d [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
Dianne Hackborn466ed242011-07-21 18:16:31 -0700364 * <var>token</var> that are in the message queue. If <var>token</var> is null,
365 * all callbacks will be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 */
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 */
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 */
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 */
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
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 */
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 */
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 */
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 */
515 public final void removeMessages(int what) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800516 mQueue.removeMessages(this, what, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 }
518
519 /**
520 * Remove any pending posts of messages with code 'what' and whose obj is
Jeff Brown32c81132012-04-30 16:28:32 -0700521 * 'object' that are in the message queue. If <var>object</var> is null,
Dianne Hackborn466ed242011-07-21 18:16:31 -0700522 * all messages will be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 */
524 public final void removeMessages(int what, Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800525 mQueue.removeMessages(this, what, object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 }
527
528 /**
529 * Remove any pending posts of callbacks and sent messages whose
Dianne Hackborn466ed242011-07-21 18:16:31 -0700530 * <var>obj</var> is <var>token</var>. If <var>token</var> is null,
531 * all callbacks and messages will be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 */
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 */
541 public final boolean hasMessages(int what) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800542 return mQueue.hasMessages(this, what, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 }
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 */
549 public final boolean hasMessages(int what, Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800550 return mQueue.hasMessages(this, what, object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 }
552
Romain Guyba6be8a2012-04-23 18:22:09 -0700553 /**
554 * Check if there are any pending posts of messages with callback r in
555 * the message queue.
556 *
557 * @hide
558 */
559 public final boolean hasCallbacks(Runnable r) {
560 return mQueue.hasMessages(this, r, null);
561 }
562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 // if we can get rid of this method, the handler need not remember its loop
564 // we could instead export a getMessageQueue() method...
565 public final Looper getLooper() {
566 return mLooper;
567 }
568
569 public final void dump(Printer pw, String prefix) {
570 pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
571 if (mLooper == null) {
572 pw.println(prefix + "looper uninitialized");
573 } else {
574 mLooper.dump(pw, prefix + " ");
575 }
576 }
577
578 @Override
579 public String toString() {
Kristian Monsen588d8562011-08-04 12:55:33 +0100580 return "Handler (" + getClass().getName() + ") {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 + Integer.toHexString(System.identityHashCode(this))
582 + "}";
583 }
584
585 final IMessenger getIMessenger() {
586 synchronized (mQueue) {
587 if (mMessenger != null) {
588 return mMessenger;
589 }
590 mMessenger = new MessengerImpl();
591 return mMessenger;
592 }
593 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 private final class MessengerImpl extends IMessenger.Stub {
596 public void send(Message msg) {
597 Handler.this.sendMessage(msg);
598 }
599 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700600
Romain Guyba6be8a2012-04-23 18:22:09 -0700601 private static Message getPostMessage(Runnable r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 Message m = Message.obtain();
603 m.callback = r;
604 return m;
605 }
606
Romain Guyba6be8a2012-04-23 18:22:09 -0700607 private static Message getPostMessage(Runnable r, Object token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 Message m = Message.obtain();
609 m.obj = token;
610 m.callback = r;
611 return m;
612 }
613
Romain Guyba6be8a2012-04-23 18:22:09 -0700614 private static void handleCallback(Message message) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 message.callback.run();
616 }
617
618 final MessageQueue mQueue;
619 final Looper mLooper;
620 final Callback mCallback;
621 IMessenger mMessenger;
622}