[go: nahoru, domu]

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
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 then 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     * @param msg A {@link android.os.Message Message} object
78     * @return True if no further handling is desired
79     */
80    public interface Callback {
81        public boolean handleMessage(Message msg);
82    }
83
84    /**
85     * Subclasses must implement this to receive messages.
86     */
87    public void handleMessage(Message msg) {
88    }
89
90    /**
91     * Handle system messages here.
92     */
93    public void dispatchMessage(Message msg) {
94        if (msg.callback != null) {
95            handleCallback(msg);
96        } else {
97            if (mCallback != null) {
98                if (mCallback.handleMessage(msg)) {
99                    return;
100                }
101            }
102            handleMessage(msg);
103        }
104    }
105
106    /**
107     * Default constructor associates this handler with the {@link Looper} for the
108     * current thread.
109     *
110     * If this thread does not have a looper, this handler won't be able to receive messages
111     * so an exception is thrown.
112     */
113    public Handler() {
114        this(null, false);
115    }
116
117    /**
118     * Constructor associates this handler with the {@link Looper} for the
119     * current thread and takes a callback interface in which you can handle
120     * messages.
121     *
122     * If this thread does not have a looper, this handler won't be able to receive messages
123     * so an exception is thrown.
124     *
125     * @param callback The callback interface in which to handle messages, or null.
126     */
127    public Handler(Callback callback) {
128        this(callback, false);
129    }
130
131    /**
132     * Use the provided {@link Looper} instead of the default one.
133     *
134     * @param looper The looper, must not be null.
135     */
136    public Handler(Looper looper) {
137        this(looper, null, false);
138    }
139
140    /**
141     * Use the provided {@link Looper} instead of the default one and take a callback
142     * interface in which to handle messages.
143     *
144     * @param looper The looper, must not be null.
145     * @param callback The callback interface in which to handle messages, or null.
146     */
147    public Handler(Looper looper, Callback callback) {
148        this(looper, callback, false);
149    }
150
151    /**
152     * Use the {@link Looper} for the current thread
153     * and set whether the handler should be asynchronous.
154     *
155     * Handlers are synchronous by default unless this constructor is used to make
156     * one that is strictly asynchronous.
157     *
158     * Asynchronous messages represent interrupts or events that do not require global ordering
159     * with respect to synchronous messages.  Asynchronous messages are not subject to
160     * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
161     *
162     * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
163     * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
164     *
165     * @hide
166     */
167    public Handler(boolean async) {
168        this(null, async);
169    }
170
171    /**
172     * Use the {@link Looper} for the current thread with the specified callback interface
173     * and set whether the handler should be asynchronous.
174     *
175     * Handlers are synchronous by default unless this constructor is used to make
176     * one that is strictly asynchronous.
177     *
178     * Asynchronous messages represent interrupts or events that do not require global ordering
179     * with respect to synchronous messages.  Asynchronous messages are not subject to
180     * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
181     *
182     * @param callback The callback interface in which to handle messages, or null.
183     * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
184     * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
185     *
186     * @hide
187     */
188    public Handler(Callback callback, boolean async) {
189        if (FIND_POTENTIAL_LEAKS) {
190            final Class<? extends Handler> klass = getClass();
191            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
192                    (klass.getModifiers() & Modifier.STATIC) == 0) {
193                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
194                    klass.getCanonicalName());
195            }
196        }
197
198        mLooper = Looper.myLooper();
199        if (mLooper == null) {
200            throw new RuntimeException(
201                "Can't create handler inside thread that has not called Looper.prepare()");
202        }
203        mQueue = mLooper.mQueue;
204        mCallback = callback;
205        mAsynchronous = async;
206    }
207
208    /**
209     * Use the provided {@link Looper} instead of the default one and take a callback
210     * interface in which to handle messages.  Also set whether the handler
211     * should be asynchronous.
212     *
213     * Handlers are synchronous by default unless this constructor is used to make
214     * one that is strictly asynchronous.
215     *
216     * Asynchronous messages represent interrupts or events that do not require global ordering
217     * with respect to synchronous messages.  Asynchronous messages are not subject to
218     * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
219     *
220     * @param looper The looper, must not be null.
221     * @param callback The callback interface in which to handle messages, or null.
222     * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
223     * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
224     *
225     * @hide
226     */
227    public Handler(Looper looper, Callback callback, boolean async) {
228        mLooper = looper;
229        mQueue = looper.mQueue;
230        mCallback = callback;
231        mAsynchronous = async;
232    }
233
234    /** {@hide} */
235    public String getTraceName(Message message) {
236        final StringBuilder sb = new StringBuilder();
237        sb.append(getClass().getName()).append(": ");
238        if (message.callback != null) {
239            sb.append(message.callback.getClass().getName());
240        } else {
241            sb.append("#").append(message.what);
242        }
243        return sb.toString();
244    }
245
246    /**
247     * Returns a string representing the name of the specified message.
248     * The default implementation will either return the class name of the
249     * message callback if any, or the hexadecimal representation of the
250     * message "what" field.
251     *
252     * @param message The message whose name is being queried
253     */
254    public String getMessageName(Message message) {
255        if (message.callback != null) {
256            return message.callback.getClass().getName();
257        }
258        return "0x" + Integer.toHexString(message.what);
259    }
260
261    /**
262     * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
263     * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
264     *  If you don't want that facility, just call Message.obtain() instead.
265     */
266    public final Message obtainMessage()
267    {
268        return Message.obtain(this);
269    }
270
271    /**
272     * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message.
273     *
274     * @param what Value to assign to the returned Message.what field.
275     * @return A Message from the global message pool.
276     */
277    public final Message obtainMessage(int what)
278    {
279        return Message.obtain(this, what);
280    }
281
282    /**
283     *
284     * Same as {@link #obtainMessage()}, except that it also sets the what and obj members
285     * of the returned Message.
286     *
287     * @param what Value to assign to the returned Message.what field.
288     * @param obj Value to assign to the returned Message.obj field.
289     * @return A Message from the global message pool.
290     */
291    public final Message obtainMessage(int what, Object obj)
292    {
293        return Message.obtain(this, what, obj);
294    }
295
296    /**
297     *
298     * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned
299     * Message.
300     * @param what Value to assign to the returned Message.what field.
301     * @param arg1 Value to assign to the returned Message.arg1 field.
302     * @param arg2 Value to assign to the returned Message.arg2 field.
303     * @return A Message from the global message pool.
304     */
305    public final Message obtainMessage(int what, int arg1, int arg2)
306    {
307        return Message.obtain(this, what, arg1, arg2);
308    }
309
310    /**
311     *
312     * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the
313     * returned Message.
314     * @param what Value to assign to the returned Message.what field.
315     * @param arg1 Value to assign to the returned Message.arg1 field.
316     * @param arg2 Value to assign to the returned Message.arg2 field.
317     * @param obj Value to assign to the returned Message.obj field.
318     * @return A Message from the global message pool.
319     */
320    public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
321    {
322        return Message.obtain(this, what, arg1, arg2, obj);
323    }
324
325    /**
326     * Causes the Runnable r to be added to the message queue.
327     * The runnable will be run on the thread to which this handler is
328     * attached.
329     *
330     * @param r The Runnable that will be executed.
331     *
332     * @return Returns true if the Runnable was successfully placed in to the
333     *         message queue.  Returns false on failure, usually because the
334     *         looper processing the message queue is exiting.
335     */
336    public final boolean post(Runnable r)
337    {
338       return  sendMessageDelayed(getPostMessage(r), 0);
339    }
340
341    /**
342     * Causes the Runnable r to be added to the message queue, to be run
343     * at a specific time given by <var>uptimeMillis</var>.
344     * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
345     * Time spent in deep sleep will add an additional delay to execution.
346     * The runnable will be run on the thread to which this handler is attached.
347     *
348     * @param r The Runnable that will be executed.
349     * @param uptimeMillis The absolute time at which the callback should run,
350     *         using the {@link android.os.SystemClock#uptimeMillis} time-base.
351     *
352     * @return Returns true if the Runnable was successfully placed in to the
353     *         message queue.  Returns false on failure, usually because the
354     *         looper processing the message queue is exiting.  Note that a
355     *         result of true does not mean the Runnable will be processed -- if
356     *         the looper is quit before the delivery time of the message
357     *         occurs then the message will be dropped.
358     */
359    public final boolean postAtTime(Runnable r, long uptimeMillis)
360    {
361        return sendMessageAtTime(getPostMessage(r), uptimeMillis);
362    }
363
364    /**
365     * Causes the Runnable r to be added to the message queue, to be run
366     * at a specific time given by <var>uptimeMillis</var>.
367     * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
368     * Time spent in deep sleep will add an additional delay to execution.
369     * The runnable will be run on the thread to which this handler is attached.
370     *
371     * @param r The Runnable that will be executed.
372     * @param uptimeMillis The absolute time at which the callback should run,
373     *         using the {@link android.os.SystemClock#uptimeMillis} time-base.
374     *
375     * @return Returns true if the Runnable was successfully placed in to the
376     *         message queue.  Returns false on failure, usually because the
377     *         looper processing the message queue is exiting.  Note that a
378     *         result of true does not mean the Runnable will be processed -- if
379     *         the looper is quit before the delivery time of the message
380     *         occurs then the message will be dropped.
381     *
382     * @see android.os.SystemClock#uptimeMillis
383     */
384    public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
385    {
386        return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
387    }
388
389    /**
390     * Causes the Runnable r to be added to the message queue, to be run
391     * after the specified amount of time elapses.
392     * The runnable will be run on the thread to which this handler
393     * is attached.
394     * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
395     * Time spent in deep sleep will add an additional delay to execution.
396     *
397     * @param r The Runnable that will be executed.
398     * @param delayMillis The delay (in milliseconds) until the Runnable
399     *        will be executed.
400     *
401     * @return Returns true if the Runnable was successfully placed in to the
402     *         message queue.  Returns false on failure, usually because the
403     *         looper processing the message queue is exiting.  Note that a
404     *         result of true does not mean the Runnable will be processed --
405     *         if the looper is quit before the delivery time of the message
406     *         occurs then the message will be dropped.
407     */
408    public final boolean postDelayed(Runnable r, long delayMillis)
409    {
410        return sendMessageDelayed(getPostMessage(r), delayMillis);
411    }
412
413    /**
414     * Posts a message to an object that implements Runnable.
415     * Causes the Runnable r to executed on the next iteration through the
416     * message queue. The runnable will be run on the thread to which this
417     * handler is attached.
418     * <b>This method is only for use in very special circumstances -- it
419     * can easily starve the message queue, cause ordering problems, or have
420     * other unexpected side-effects.</b>
421     *
422     * @param r The Runnable that will be executed.
423     *
424     * @return Returns true if the message was successfully placed in to the
425     *         message queue.  Returns false on failure, usually because the
426     *         looper processing the message queue is exiting.
427     */
428    public final boolean postAtFrontOfQueue(Runnable r)
429    {
430        return sendMessageAtFrontOfQueue(getPostMessage(r));
431    }
432
433    /**
434     * Runs the specified task synchronously.
435     * <p>
436     * If the current thread is the same as the handler thread, then the runnable
437     * runs immediately without being enqueued.  Otherwise, posts the runnable
438     * to the handler and waits for it to complete before returning.
439     * </p><p>
440     * This method is dangerous!  Improper use can result in deadlocks.
441     * Never call this method while any locks are held or use it in a
442     * possibly re-entrant manner.
443     * </p><p>
444     * This method is occasionally useful in situations where a background thread
445     * must synchronously await completion of a task that must run on the
446     * handler's thread.  However, this problem is often a symptom of bad design.
447     * Consider improving the design (if possible) before resorting to this method.
448     * </p><p>
449     * One example of where you might want to use this method is when you just
450     * set up a Handler thread and need to perform some initialization steps on
451     * it before continuing execution.
452     * </p><p>
453     * If timeout occurs then this method returns <code>false</code> but the runnable
454     * will remain posted on the handler and may already be in progress or
455     * complete at a later time.
456     * </p><p>
457     * When using this method, be sure to use {@link Looper#quitSafely} when
458     * quitting the looper.  Otherwise {@link #runWithScissors} may hang indefinitely.
459     * (TODO: We should fix this by making MessageQueue aware of blocking runnables.)
460     * </p>
461     *
462     * @param r The Runnable that will be executed synchronously.
463     * @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
464     *
465     * @return Returns true if the Runnable was successfully executed.
466     *         Returns false on failure, usually because the
467     *         looper processing the message queue is exiting.
468     *
469     * @hide This method is prone to abuse and should probably not be in the API.
470     * If we ever do make it part of the API, we might want to rename it to something
471     * less funny like runUnsafe().
472     */
473    public final boolean runWithScissors(final Runnable r, long timeout) {
474        if (r == null) {
475            throw new IllegalArgumentException("runnable must not be null");
476        }
477        if (timeout < 0) {
478            throw new IllegalArgumentException("timeout must be non-negative");
479        }
480
481        if (Looper.myLooper() == mLooper) {
482            r.run();
483            return true;
484        }
485
486        BlockingRunnable br = new BlockingRunnable(r);
487        return br.postAndWait(this, timeout);
488    }
489
490    /**
491     * Remove any pending posts of Runnable r that are in the message queue.
492     */
493    public final void removeCallbacks(Runnable r)
494    {
495        mQueue.removeMessages(this, r, null);
496    }
497
498    /**
499     * Remove any pending posts of Runnable <var>r</var> with Object
500     * <var>token</var> that are in the message queue.  If <var>token</var> is null,
501     * all callbacks will be removed.
502     */
503    public final void removeCallbacks(Runnable r, Object token)
504    {
505        mQueue.removeMessages(this, r, token);
506    }
507
508    /**
509     * Pushes a message onto the end of the message queue after all pending messages
510     * before the current time. It will be received in {@link #handleMessage},
511     * in the thread attached to this handler.
512     *
513     * @return Returns true if the message was successfully placed in to the
514     *         message queue.  Returns false on failure, usually because the
515     *         looper processing the message queue is exiting.
516     */
517    public final boolean sendMessage(Message msg)
518    {
519        return sendMessageDelayed(msg, 0);
520    }
521
522    /**
523     * Sends a Message containing only the what value.
524     *
525     * @return Returns true if the message was successfully placed in to the
526     *         message queue.  Returns false on failure, usually because the
527     *         looper processing the message queue is exiting.
528     */
529    public final boolean sendEmptyMessage(int what)
530    {
531        return sendEmptyMessageDelayed(what, 0);
532    }
533
534    /**
535     * Sends a Message containing only the what value, to be delivered
536     * after the specified amount of time elapses.
537     * @see #sendMessageDelayed(android.os.Message, long)
538     *
539     * @return Returns true if the message was successfully placed in to the
540     *         message queue.  Returns false on failure, usually because the
541     *         looper processing the message queue is exiting.
542     */
543    public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
544        Message msg = Message.obtain();
545        msg.what = what;
546        return sendMessageDelayed(msg, delayMillis);
547    }
548
549    /**
550     * Sends a Message containing only the what value, to be delivered
551     * at a specific time.
552     * @see #sendMessageAtTime(android.os.Message, long)
553     *
554     * @return Returns true if the message was successfully placed in to the
555     *         message queue.  Returns false on failure, usually because the
556     *         looper processing the message queue is exiting.
557     */
558
559    public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
560        Message msg = Message.obtain();
561        msg.what = what;
562        return sendMessageAtTime(msg, uptimeMillis);
563    }
564
565    /**
566     * Enqueue a message into the message queue after all pending messages
567     * before (current time + delayMillis). You will receive it in
568     * {@link #handleMessage}, in the thread attached to this handler.
569     *
570     * @return Returns true if the message was successfully placed in to the
571     *         message queue.  Returns false on failure, usually because the
572     *         looper processing the message queue is exiting.  Note that a
573     *         result of true does not mean the message will be processed -- if
574     *         the looper is quit before the delivery time of the message
575     *         occurs then the message will be dropped.
576     */
577    public final boolean sendMessageDelayed(Message msg, long delayMillis)
578    {
579        if (delayMillis < 0) {
580            delayMillis = 0;
581        }
582        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
583    }
584
585    /**
586     * Enqueue a message into the message queue after all pending messages
587     * before the absolute time (in milliseconds) <var>uptimeMillis</var>.
588     * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
589     * Time spent in deep sleep will add an additional delay to execution.
590     * You will receive it in {@link #handleMessage}, in the thread attached
591     * to this handler.
592     *
593     * @param uptimeMillis The absolute time at which the message should be
594     *         delivered, using the
595     *         {@link android.os.SystemClock#uptimeMillis} time-base.
596     *
597     * @return Returns true if the message was successfully placed in to the
598     *         message queue.  Returns false on failure, usually because the
599     *         looper processing the message queue is exiting.  Note that a
600     *         result of true does not mean the message will be processed -- if
601     *         the looper is quit before the delivery time of the message
602     *         occurs then the message will be dropped.
603     */
604    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
605        MessageQueue queue = mQueue;
606        if (queue == null) {
607            RuntimeException e = new RuntimeException(
608                    this + " sendMessageAtTime() called with no mQueue");
609            Log.w("Looper", e.getMessage(), e);
610            return false;
611        }
612        return enqueueMessage(queue, msg, uptimeMillis);
613    }
614
615    /**
616     * Enqueue a message at the front of the message queue, to be processed on
617     * the next iteration of the message loop.  You will receive it in
618     * {@link #handleMessage}, in the thread attached to this handler.
619     * <b>This method is only for use in very special circumstances -- it
620     * can easily starve the message queue, cause ordering problems, or have
621     * other unexpected side-effects.</b>
622     *
623     * @return Returns true if the message was successfully placed in to the
624     *         message queue.  Returns false on failure, usually because the
625     *         looper processing the message queue is exiting.
626     */
627    public final boolean sendMessageAtFrontOfQueue(Message msg) {
628        MessageQueue queue = mQueue;
629        if (queue == null) {
630            RuntimeException e = new RuntimeException(
631                this + " sendMessageAtTime() called with no mQueue");
632            Log.w("Looper", e.getMessage(), e);
633            return false;
634        }
635        return enqueueMessage(queue, msg, 0);
636    }
637
638    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
639        msg.target = this;
640        if (mAsynchronous) {
641            msg.setAsynchronous(true);
642        }
643        return queue.enqueueMessage(msg, uptimeMillis);
644    }
645
646    /**
647     * Remove any pending posts of messages with code 'what' that are in the
648     * message queue.
649     */
650    public final void removeMessages(int what) {
651        mQueue.removeMessages(this, what, null);
652    }
653
654    /**
655     * Remove any pending posts of messages with code 'what' and whose obj is
656     * 'object' that are in the message queue.  If <var>object</var> is null,
657     * all messages will be removed.
658     */
659    public final void removeMessages(int what, Object object) {
660        mQueue.removeMessages(this, what, object);
661    }
662
663    /**
664     * Remove any pending posts of callbacks and sent messages whose
665     * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
666     * all callbacks and messages will be removed.
667     */
668    public final void removeCallbacksAndMessages(Object token) {
669        mQueue.removeCallbacksAndMessages(this, token);
670    }
671
672    /**
673     * Check if there are any pending posts of messages with code 'what' in
674     * the message queue.
675     */
676    public final boolean hasMessages(int what) {
677        return mQueue.hasMessages(this, what, null);
678    }
679
680    /**
681     * Check if there are any pending posts of messages with code 'what' and
682     * whose obj is 'object' in the message queue.
683     */
684    public final boolean hasMessages(int what, Object object) {
685        return mQueue.hasMessages(this, what, object);
686    }
687
688    /**
689     * Check if there are any pending posts of messages with callback r in
690     * the message queue.
691     *
692     * @hide
693     */
694    public final boolean hasCallbacks(Runnable r) {
695        return mQueue.hasMessages(this, r, null);
696    }
697
698    // if we can get rid of this method, the handler need not remember its loop
699    // we could instead export a getMessageQueue() method...
700    public final Looper getLooper() {
701        return mLooper;
702    }
703
704    public final void dump(Printer pw, String prefix) {
705        pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
706        if (mLooper == null) {
707            pw.println(prefix + "looper uninitialized");
708        } else {
709            mLooper.dump(pw, prefix + "  ");
710        }
711    }
712
713    @Override
714    public String toString() {
715        return "Handler (" + getClass().getName() + ") {"
716        + Integer.toHexString(System.identityHashCode(this))
717        + "}";
718    }
719
720    final IMessenger getIMessenger() {
721        synchronized (mQueue) {
722            if (mMessenger != null) {
723                return mMessenger;
724            }
725            mMessenger = new MessengerImpl();
726            return mMessenger;
727        }
728    }
729
730    private final class MessengerImpl extends IMessenger.Stub {
731        public void send(Message msg) {
732            msg.sendingUid = Binder.getCallingUid();
733            Handler.this.sendMessage(msg);
734        }
735    }
736
737    private static Message getPostMessage(Runnable r) {
738        Message m = Message.obtain();
739        m.callback = r;
740        return m;
741    }
742
743    private static Message getPostMessage(Runnable r, Object token) {
744        Message m = Message.obtain();
745        m.obj = token;
746        m.callback = r;
747        return m;
748    }
749
750    private static void handleCallback(Message message) {
751        message.callback.run();
752    }
753
754    final Looper mLooper;
755    final MessageQueue mQueue;
756    final Callback mCallback;
757    final boolean mAsynchronous;
758    IMessenger mMessenger;
759
760    private static final class BlockingRunnable implements Runnable {
761        private final Runnable mTask;
762        private boolean mDone;
763
764        public BlockingRunnable(Runnable task) {
765            mTask = task;
766        }
767
768        @Override
769        public void run() {
770            try {
771                mTask.run();
772            } finally {
773                synchronized (this) {
774                    mDone = true;
775                    notifyAll();
776                }
777            }
778        }
779
780        public boolean postAndWait(Handler handler, long timeout) {
781            if (!handler.post(this)) {
782                return false;
783            }
784
785            synchronized (this) {
786                if (timeout > 0) {
787                    final long expirationTime = SystemClock.uptimeMillis() + timeout;
788                    while (!mDone) {
789                        long delay = expirationTime - SystemClock.uptimeMillis();
790                        if (delay <= 0) {
791                            return false; // timeout
792                        }
793                        try {
794                            wait(delay);
795                        } catch (InterruptedException ex) {
796                        }
797                    }
798                } else {
799                    while (!mDone) {
800                        try {
801                            wait();
802                        } catch (InterruptedException ex) {
803                        }
804                    }
805                }
806            }
807            return true;
808        }
809    }
810}
811