OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / core / java / android / os / Handler.java
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 than 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 {
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     }
566
567     private final class MessengerImpl extends IMessenger.Stub {
568         public void send(Message msg) {
569             Handler.this.sendMessage(msg);
570         }
571     }
572
573     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 }