• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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