blob: 3b2bf1e81c80edf30bf05c3514a7cc3ea92ca386 [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
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 */
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 /**
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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...
537 public final Looper getLooper() {
538 return mLooper;
539 }
540
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
551 public String toString() {
552 return "Handler{"
553 + Integer.toHexString(System.identityHashCode(this))
554 + "}";
555 }
556
557 final IMessenger getIMessenger() {
558 synchronized (mQueue) {
559 if (mMessenger != null) {
560 return mMessenger;
561 }
562 mMessenger = new MessengerImpl();
563 return mMessenger;
564 }
565 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 private final class MessengerImpl extends IMessenger.Stub {
568 public void send(Message msg) {
569 Handler.this.sendMessage(msg);
570 }
571 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573 private final Message getPostMessage(Runnable r) {
574 Message m = Message.obtain();
575 m.callback = r;
576 return m;
577 }
578
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
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}