原文地址:http://blog.csdn.net/wcs542882916
packageandroid.os;
importandroid.util.Log;
importandroid.util.Printer;
importjava.lang.reflect.Modifier;
importandroid.os.Process;
importjava.util.Iterator;
import android.os.Process;
/**
* AHandler allows you to send and process {@link Message} and Runnable objects
*associated with a thread's {@linkMessageQueue}. Each Handler instance is
*associated with a single thread and that thread's message queue. When you
*create a new Handler, it is bound to the thread / message queue of the thread
*that is creating it -- from thatpoint on, it will deliver messages and
* runnablesto that message queue and execute them as they come out of the
*message queue.
*
*There are two main uses for a Handler: (1) to schedule messages and runnables
* tobe executed as some point in the future; and (2) to enqueue an action to
* beperformed on a different thread than your own.
*
*Scheduling messages is accomplished with the {@link #post},
* {@link #postAtTime(Runnable, long)}, {@link #postDelayed},
* {@link #sendEmptyMessage}, {@link #sendMessage}, {@link #sendMessageAtTime},
*and {@link #sendMessageDelayed} methods. The post versions allow you
* toenqueue Runnable objects to be called by the message queue when they are
*received; the sendMessage versions allow you to enqueue a
* {@link Message} object containing a bundle of data thatwill be processed by
*the Handler's {@link #handleMessage} method (requiring that you implement a
*subclass of Handler).
*
*When posting or sending to a Handler, you can either allow the item to be
*processed as soon as the message queue is ready to do so, or specify a delay
*before it gets processed or absolute time for it to be processed. The latter
*two allow you to implement timeouts, ticks, and other timing-based behavior.
*
*When a process is created for your application, its main thread is dedicated
* torunning a message queue that takes care of managing the top-level
*application objects (activities, broadcast receivers, etc) and any windows
*they create. You can create your own threads, and communicate back with the
*main application thread through a Handler. This is done by calling the same
*post or sendMessage methods as before, but from your new
*thread. The given Runnable or Message will then be scheduled in the Handler's
*message queue and processed when appropriate.
*
* 一个Handler允许你去发送和处理Message和Runnable对象,
* 而Message和Runnable对象是与一个线程的MessageQueue相关的。
* 每个Handler实例与一个单独的线程相关且和这个线程的MessageQueue相关。
* 当你创建一个Handler的时候,这个Handler会绑定到创建这个Handler的线程和线程的MessageQueue。
* 从创建Handler开始,Handler将会发送Message 和Runnable到对应的MessageQueue,
* 并且在Message和Runnable被移出MessageQueue的时候处理。
*
*Handler有两个主要用法:
* (1)计划在将来的某个时间点处理Message和Runnable。
* (2)在不同的线程里将一个动作加入Handler所对应的队列去执行,这个线程不只是创建Handler的线程。
*
* 计划Message用以下这些方法来完成,#post,#postAtTime(Runnable,long),
*#postDelayed,#sendEmptyMessage,#sendMessage,
*#sendMessageAtTime,#sendMessageDelayed。
* 这个post版本的方法允许你把Runnable对象加入队列,在Runnable对象移出的时候被MessageQueue调用;
* 这个sendMessage版本的方法允许你把Message对象(Message对象里包含一些数据)加入队列,
* 并且被Handler的#handleMessage方法处理,
* 这个sendMessage版本需要你实现Handler的子类,重写#handleMessage方法。
*
* 当posting 或 sending
* 给Handler时,你能允许这item在MessageQueue准备好后及时的被处理或者指定一个延迟时间,
* 又或者指定一个绝对时间点。
*#sendMessageAtTime,#sendMessageDelayed这两个方法允许你实现延时,定时,和其它基于定时的操作。
*
* 当你的应用进程被创建的时候,应用的主线程就一直致力于运行一个MessageQueue,
* 主线程致力于管理顶级应用对象(activity,broadcast receivers,etc) 和任何创建的窗口。
* 你可以创建你自己的线程,然后通过Handler与应用主线程通信。这种与主线程的通信方式被实现,
* 也是像之前一样同样通过post和sendMessage方法。
*Runnable对象和Message将要被加入Handler的MessageQueue中,在合适的时候被处理。
*/
public class Handler {
/**
* Set this flag to true to detect anonymous,local or member classes that
* extend this Handler class and that are notstatic. These kind of classes
* can potentially create leaks.
*
* 设置这个flag为true来检测继承Handler类并且非静态的匿名、本地、成员类。
* 这一类型的类会潜在的产生泄露。
*/
private static final boolean FIND_POTENTIAL_LEAKS = false;
private static final String TAG = "Handler";
/**
* Callback interface you can use wheninstantiating a Handler to avoid
* having to implement your own subclass ofHandler.
*
* @param msg
* A {@link android.os.Message Message} object
* @return True if no further handling is desired
*
* 在实例化一个Handler的时候你可以使用这个回调接口,这样就可以避免实现你自己的Handler子类
* 在使用Handler的时候通常会重写Handler类的#handleMessage方法,
* 而重写这个方法无非就是继承Handler重写该方法
* 或者创建的时候重写该方法
*
* 如果Callback#handleMessage方法返回false,
* 那么Handler还会执行Handler#handleMessage方法
* 否则只执行Callback#handleMessage方法
*/
public interfaceCallback {
public booleanhandleMessage(Message msg);
}
/**
* Subclasses must implement this to receivemessages.
*
* 子类必须实现这个方法来接受消息
*/
public voidhandleMessage(Message msg) {
}
/**
* Handle system messages here.
*
* 这个地方负责分发处理Message
*
* 处理过程分析:
* 1.判断Message是否有callback(msg.callback是Runnable对象的引用),
* 有则执行Runnable代码且分发Message结束,否则执行第2步。
* 2.判断Handler#mCallback成员变量是否为null,为null执行第3步,
* 不为null执行mCallback#handleMessage,该方法有返回值,
* 返回true分发结束,返回false则还会执行第3步。
* 3.执行Handler#handleMessage。
*
*/
public voiddispatchMessage(Message msg) {
if (msg.callback != null) { //这部分用来处理Handler#post方法
handleCallback(msg);
}else {
if (mCallback!= null){ //这部分用来处理Handler#Callback接口,如果使用
if (mCallback.handleMessage(msg)){
return;
}
}
handleMessage(msg);
}
}
/**
* Default constructor associates this handlerwith the {@link Looper} for
* the current thread.
*
* If this thread does not have a looper, thishandler won't be able to
* receive messages so an exception is thrown.
*
* 默认构造方法,把Handler和当前线程的Looper联系起来
* 如果这个线程没有Looper,这个Handler将不会接收到Message,
* 并且会抛出一个exception
*/
public Handler() {
this(null,false);//Handler(Callback callback, boolean async)
}
/**
* Constructor associates this handler with the{@link Looper} for the
* current thread and takes a callbackinterface in which you can handle
* messages.
*
* If this thread does not have a looper, thishandler won't be able to
* receive messages so an exception is thrown.
*
* @param callback
* The callback interface in which to handle messages, or null.
*
* callback Callback接口,接口里去处理Message,或者为null
*/
public Handler(Callback callback) {
this(callback, false);
}
/**
* Use the provided {@link Looper} instead of the default one.
*
* @param looper
* The looper, must not be null.
*
* 使用提供的Looper替代默认的Looper,默认是当前线程的Looper
* 参数looper不能为null
*/
public Handler(Looper looper) {
this(looper, null, false);
}
/**
* Use the provided {@link Looper} instead of the default one and take a
* callback interface in which to handlemessages.
*
* @param looper
* The looper, must not be null.
* @param callback
* The callback interface in which to handle messages, or null.
*
* 同上
*/
public Handler(Looper looper, Callback callback) {
this(looper, callback, false);
}
/**
* Use the {@link Looper} for the current thread and set whether thehandler
* should be asynchronous.
*
* Handlers are synchronous by default unlessthis constructor is used to
* make one that is strictly asynchronous.
*
* Asynchronous messages represent interruptsor events that do not require
* global ordering with represent tosynchronous messages. Asynchronous
* messages are not subject to thesynchronization barriers introduced by
* {@linkMessageQueue#enqueueSyncBarrier(long)}.
*
* @param async
* If true, the handler calls
* {@link Message#setAsynchronous(boolean)} for each
* {@link Message} that is sent to it or {@linkRunnable} that is
* posted to it.
*
* @hide
*/
//异步Message暂时不用到
public Handler(boolean async) {
this(null,async);
}
/**
* Use the {@link Looper} for the current thread with the specifiedcallback
* interface and set whether the handler shouldbe asynchronous.
*
* Handlers are synchronous by default unlessthis constructor is used to
* make one that is strictly asynchronous.
*
* Asynchronous messages represent interruptsor events that do not require
* global ordering with represent tosynchronous messages. Asynchronous
* messages are not subject to thesynchronization barriers introduced by
* {@linkMessageQueue#enqueueSyncBarrier(long)}.
*
* @param callback
* The callback interface in which to handle messages, or null.
* @param async
* If true, the handler calls
* {@link Message#setAsynchronous(boolean)} for each
* {@link Message} that is sent to it or {@link Runnable} that is
* posted to it.
*
* @hide
*/
public Handler(Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() ||klass.isMemberClass() || klass
.isLocalClass())
&&(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG,
"The following Handler class should be static or leaks might occur:"
+klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();
if (mLooper== null){
throw newRuntimeException(
"Can't create handler inside thread that has not calledLooper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
/**
* Use the provided {@link Looper} instead of the default one and take a
* callback interface in which to handlemessages. Also set whether the
* handler should be asynchronous.
*
* Handlers are synchronous by default unlessthis constructor is used to
* make one that is strictly asynchronous.
*
* Asynchronous messages represent interruptsor events that do not require
* global ordering with represent tosynchronous messages. Asynchronous
* messages are not subject to thesynchronization barriers introduced by
* {@linkMessageQueue#enqueueSyncBarrier(long)}.
*
* @param looper
* The looper, must not be null.
* @param callback
* The callback interface in which to handle messages, or null.
* @param async
* If true, the handler calls
* {@link Message#setAsynchronous(boolean)} for each
* {@link Message} that is sent to it or {@linkRunnable} that is
* posted to it.
*
* @hide
*/
//异步Message暂时不用到
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
/**
* Returns a string representing the name ofthe specified message. The
* default implementation will either returnthe class name of the message
* callback if any, or the hexadecimalrepresentation of the message "what"
* field.
*
* @param message
* The message whose name is being queried
*
* 返回一个字符串代表指定Message的名字。
* 默认实现是返回Message里callback(Runnable)的类名如果有的话,
* 或者返回一个十六进制数字的字符串,这个字符串表示的是Message#what 域的值。
*/
public String getMessageName(Message message) {
if (message.callback != null) {
return message.callback.getClass().getName();
}
return "0x"+ Integer.toHexString(message.what);
}
/**
* Returns a new {@link android.os.Message Message} from the global message
* pool. More efficient than creating andallocating new instances. The
* retrieved message has its handler set tothis instance (Message.target ==
* this). If you don't want that facility, justcall Message.obtain()
* instead.
*
* 返回一个新的Message,返回的Message都是从全局Message池里获取的。
* 这样做更有效率比创建和开辟新的实例。
* 这个或取的Message对象有它自己的Handler,(Message.target == this)。
* 如果你不想这样做,可以调用Message.obtain()来替代。
* Message全局消息池里Message的数量由Message#MAX_POOL_SIZE来表示,默认为50个。
*/
public finalMessage obtainMessage() {
returnMessage.obtain(this);
}
/**
* Same as {@link #obtainMessage()}, except thatit also sets the what
* member of the returned Message.
*
* @param what
* Value to assign to the returned Message.what field.
* @return A Message from the global message pool.
*
* 返回一个Message实例并且设置了what域和target域的值
*/
public finalMessage obtainMessage(intwhat) {
return Message.obtain(this, what);
}
/**
*
* Same as {@link #obtainMessage()}, except thatit also sets the what and
* obj members of the returned Message.
*
* @param what
* Value to assign to the returned Message.what field.
* @param obj
* Value to assign to the returned Message.obj field.
* @return A Message from the global message pool.
*
* 返回一个Message实例并且设置了what域的值和obj域的值
*/
public finalMessage obtainMessage(intwhat, Object obj) {
return Message.obtain(this, what, obj);
}
/**
*
* Same as {@link #obtainMessage()}, except thatit also sets the what, arg1
* and arg2 members of the returned Message.
*
* @param what
* Value to assign to the returned Message.what field.
* @param arg1
* Value to assign to the returned Message.arg1 field.
* @param arg2
* Value to assign to the returned Message.arg2 field.
* @return A Message from the global message pool.
*
* 返回一个Message实例并且设置了what域arg1域和arg2域的值
*/
public finalMessage obtainMessage(intwhat, intarg1, intarg2) {
return Message.obtain(this, what, arg1, arg2);
}
/**
*
* Same as {@link #obtainMessage()}, except thatit also sets the what, obj,
* arg1,and arg2 values on the returnedMessage.
*
* @param what
* Value to assign to the returned Message.what field.
* @param arg1
* Value to assign to the returned Message.arg1 field.
* @param arg2
* Value to assign to the returned Message.arg2 field.
* @param obj
* Value to assign to the returned Message.obj field.
* @return A Message from the global message pool.
*
* 返回一个Message实例并且设置了what域arg1域arg2域和obj域的值
*/
public finalMessage obtainMessage(intwhat, intarg1, intarg2, Object obj) {
return Message.obtain(this, what, arg1, arg2, obj);
}
/**
* Causes the Runnable r to be added to themessage queue. The runnable will
* be run on the thread to which this handleris attached.
*
* @param r
* The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* 将Runnable立刻加入MessageQueue。这个Runnable将要在Handler所在的线程上执行。
* 返回true表示Runnable被成功加入到MessageQueue。返回false表示加入失败(判断加入失败就是先判断mQueue是否为null),
* 通常处理MessageQueue的Looper是存在的。
*
* 原理就是获取一个新的Message,然后将Runnable赋值给Message的callback域,
* 在Message分发的时候就优先处理了
*/
public final boolean post(Runnable r) {
return sendMessageDelayed(getPostMessage(r),0);
}
/**
* Causes the Runnable r to be added to themessage queue, to be run at a
* specific time given by <var>uptimeMillis</var>. <b>The time-base is
* {@linkandroid.os.SystemClock#uptimeMillis}.</b> The runnable will be run
* on the thread to which this handler isattached.
*
* @param r
* The Runnable that will be executed.
* @param uptimeMillis
* The absolute time at which the callback should run, using the
* {@link android.os.SystemClock#uptimeMillis} time-base.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed -- if
* the looper is quit before the delivery time of the message occurs
* then the message will be dropped.
*
* 将Runnable在指定时间加入MessageQueue。
*/
public final boolean postAtTime(Runnable r, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r),uptimeMillis);
}
/**
* Causes the Runnable r to be added to themessage queue, to be run at a
* specific time given by <var>uptimeMillis</var>. <b>The time-base is
* {@linkandroid.os.SystemClock#uptimeMillis}.</b> The runnable will be run
* on the thread to which this handler isattached.
*
* @param r
* The Runnable that will be executed.
* @param uptimeMillis
* The absolute time at which the callback should run, using the
* {@link android.os.SystemClock#uptimeMillis} time-base.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed -- if
* the looper is quit before the delivery time of the message occurs
* then the message will be dropped.
*
* @see android.os.SystemClock#uptimeMillis
*
* 将Runnable在指定时间加入MessageQueue,并且还设置了Message#obj域的值。
*/
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r,token), uptimeMillis);
}
/**
* Causes the Runnable r to be added to themessage queue, to be run after
* the specified amount of time elapses. Therunnable will be run on the
* thread to which this handler is attached.
*
* @param r
* The Runnable that will be executed.
* @param delayMillis
* The delay (in milliseconds) until the Runnable will be
* executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed -- if
* the looper is quit before the delivery time of the message occurs
* then the message will be dropped.
*
* 将Runnable延时加入MessageQueue。
*/
public final boolean postDelayed(Runnable r, long delayMillis) {
return sendMessageDelayed(getPostMessage(r),delayMillis);
}
/**
* Posts a message to an object that implementsRunnable. Causes the
* Runnable r to executed on the next iterationthrough the message queue.
* The runnable will be run on the thread towhich this handler is attached.
* <b>This method is only for use in very special circumstances -- it can
* easily starve the message queue, causeordering problems, or have other
* unexpected side-effects.</b>
*
* @param r
* The Runnable that will be executed.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* 将Runnable插入到最前面,下一个就执行;
* 这个方法只用于非常紧急的情况,该方法可能很容易造成顺序问题,
* 阻碍其他message执行,或引起其他不希望的影响
*/
public final boolean postAtFrontOfQueue(Runnable r) {
return sendMessageAtFrontOfQueue(getPostMessage(r));
}
/**
* Runs the specified task synchronously.
* <p>
* If the current thread is the same as thehandler thread, then the
* runnable runs immediately without beingenqueued. Otherwise, posts the
* runnable to the handler and waits for it tocomplete before returning.
* </p>
* <p>
* This method is dangerous! Improper use canresult in deadlocks. Never
* call this method while any locks are held oruse it in a possibly
* re-entrant manner.
* </p>
* <p>
* This method is occasionally useful insituations where a background
* thread must synchronously await completionof a task that must run on the
* handler's thread. However, this problem isoften a symptom of bad design.
* Consider improving the design (if possible)before resorting to this
* method.
* </p>
* <p>
* One example of where you might want to usethis method is when you just
* set up a Handler thread and need to performsome initialization steps on
* it before continuing execution.
* </p>
* <p>
* If timeout occurs then this method returns <code>false</code> but the
* runnable will remain posted on the handlerand may already be in progress
* or complete at a later time.
* </p>
* <p>
* When using this method, be sure to use {@link Looper#quitSafely} when
* quitting the looper. Otherwise {@link #runWithScissors} may hang
* indefinitely. (TODO: We should fix this by making MessageQueueaware of
* blocking runnables.)
* </p>
*
* @param r
* The Runnable that will be executed synchronously.
* @param timeout
* The timeout in milliseconds, or 0 to wait indefinitely.
*
* @return Returns true if the Runnable was successfully executed. Returns
* false on failure, usually because the looper processing the
* message queue is exiting.
*
* @hide This method is prone to abuse and should probably not be in the
* API. If we ever do make it part of the API, we might want to rename
* it to something less funny like runUnsafe().
*
* 暂时不用
*/
public final boolean runWithScissors(final Runnable r, long timeout) {
if (r == null) {
throw newIllegalArgumentException("runnablemust not be null");
}
if (timeout < 0) {
throw newIllegalArgumentException("timeoutmust be non-negative");
}
if (Looper.myLooper() == mLooper) {
r.run();
return true;
}
BlockingRunnablebr = newBlockingRunnable(r);
return br.postAndWait(this, timeout);
}
/**
* Remove any pending posts of Runnable r thatare in the message queue.
*
* 移除所有挂起的 r 对象。
*/
public final void removeCallbacks(Runnable r) {
mQueue.removeMessages(this, r, null);
}
/**
* Remove any pending posts of Runnable <var>r</var> with Object
* <var>token</var> that are in the message queue. If <var>token</var> is
* null, all callbacks will be removed.
*
* 移除所有挂起的拥有token 的 r 对象,如果token为null,移除所有的挂起的 r 对象。
*/
public final void removeCallbacks(Runnable r, Object token) {
mQueue.removeMessages(this, r, token);
}
/**
* Pushes a message onto the end of the messagequeue after all pending
* messages before the current time. It will bereceived in
* {@link#handleMessage}, in the thread attached to this handler.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* 立即发送一条message
*/
public final boolean sendMessage(Message msg) {
return sendMessageDelayed(msg, 0);
}
/**
* Sends a Message containing only the whatvalue.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* 发送的message只包含what域
*/
public final boolean sendEmptyMessage(int what) {
return sendEmptyMessageDelayed(what, 0);
}
/**
* Sends a Message containing only the whatvalue, to be delivered after the
* specified amount of time elapses.
*
* @see #sendMessageDelayed(android.os.Message, long)
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* 延迟发送一条message,该message只包含what域
*/
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Messagemsg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
/**
* Sends a Message containing only the whatvalue, to be delivered at a
* specific time.
*
* @see #sendMessageAtTime(android.os.Message, long)
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* 定时间点发送
*/
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
Messagemsg = Message.obtain();
msg.what = what;
return sendMessageAtTime(msg, uptimeMillis);
}
/**
* Enqueue a message into the message queueafter all pending messages
* before (current time + delayMillis). Youwill receive it in
* {@link#handleMessage}, in the thread attached to this handler.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the message will be processed -- if
* the looper is quit before the delivery time of the message occurs
* then the message will be dropped.
*
* 延时发送message
*/
public final boolean sendMessageDelayed(Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis= 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis()+ delayMillis);
}
/**
* Enqueue a message into the message queueafter all pending messages
* before the absolute time (in milliseconds) <var>uptimeMillis</var>.
* <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b> You
* will receive it in {@link #handleMessage}, in thethread attached to this
* handler.
*
* @param uptimeMillis
* The absolute time at which the message should be delivered,
* using the {@link android.os.SystemClock#uptimeMillis}
* time-base.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the message will be processed -- if
* the looper is quit before the delivery time of the message occurs
* then the message will be dropped.
*
* 定时间点发送message
*/
public booleansendMessageAtTime(Message msg, longuptimeMillis) {
MessageQueuequeue = mQueue;
if (queue == null) {
RuntimeExceptione = newRuntimeException(this
+" sendMessageAtTime() called with no mQueue");
Log.w("Looper",e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
/**
* Enqueue a message at the front of themessage queue, to be processed on
* the next iteration of the message loop. Youwill receive it in
* {@link#handleMessage}, in the thread attached to this handler. <b>This
* method is only for use in very specialcircumstances -- it caneasily
* starve the message queue, cause orderingproblems, or have other
* unexpected side-effects.</b>
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* 插入到队列最前面,下一条就执行
*/
public final boolean sendMessageAtFrontOfQueue(Message msg) {
MessageQueuequeue = mQueue;
if (queue == null) {
RuntimeExceptione = newRuntimeException(this
+" sendMessageAtTime() called with no mQueue");
Log.w("Looper",e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, 0);
}
// / M: MSG Logger Manager @{
/**
* @hide
*/
public final void sendMonitorMessage(Message msg, long delayMillis,
long executiontimeout, long pendingtimeout, String msgLoggerName) {
if (null != MessageMonitorLogger.mMsgLoggerHandler) {
MessageMonitorLogger.MonitorMSGInfomsgMonitorInfo = new MessageMonitorLogger.MonitorMSGInfo();
msgMonitorInfo.msg= msg;
msgMonitorInfo.msgLoggerName= msgLoggerName;
msgMonitorInfo.executionTimeout= executiontimeout;
MessageMonitorLogger.monitorMsg.put(msg,msgMonitorInfo);
try {
if (pendingtimeout > 100) {
Messagemsg1 = MessageMonitorLogger.mMsgLoggerHandler
.obtainMessage(
MessageMonitorLogger.START_MONITOR_PENDING_TIMEOUT_MSG,
msgMonitorInfo);
MessageMonitorLogger.mMsgLoggerHandler.sendMessageDelayed(
msg1,delayMillis + pendingtimeout);
}else {
if (pendingtimeout != MessageMonitorLogger.DISABLE_MONITOR_PENDING_TIMEOUT_MSG)
throw newIllegalArgumentException(
"Pendingtimeout <100 ms!");
}
}catch (Exception e){
Log.d("Handler", "Pending timeout exception "+ e);
}
}else {
Log.d("Handler", "You didn't register message logger");
}
sendMessageDelayed(msg,delayMillis);
}
/**
* @hide
*/
public final void removeMonitorMessage(int what) {
Iteratoriter = MessageMonitorLogger.monitorMsg.keySet().iterator();
while (iter.hasNext()) {
Messagemsg = (Message) iter.next();
if (msg.what == what) {
MessageMonitorLogger.MonitorMSGInfomonitorMsg = MessageMonitorLogger.monitorMsg
.get(msg);
if (MessageMonitorLogger.mMsgLoggerHandler.hasMessages(
MessageMonitorLogger.START_MONITOR_PENDING_TIMEOUT_MSG,
monitorMsg)){
Log.d("Looper", "Remove monitor msg= " + msg);
MessageMonitorLogger.mMsgLoggerHandler
.removeMessages(
MessageMonitorLogger.START_MONITOR_PENDING_TIMEOUT_MSG,
monitorMsg);
MessageMonitorLogger.monitorMsg.remove(msg);
}
}
}
mQueue.removeMessages(this, what, null);
}
/**
* @hide
*/
public final void removeMonitorMessage(int what, Object object) {
Iteratoriter = MessageMonitorLogger.monitorMsg.keySet().iterator();
while (iter.hasNext()) {
Messagemsg = (Message) iter.next();
if (msg.what == what && msg.obj == object) {
MessageMonitorLogger.MonitorMSGInfomonitorMsg = MessageMonitorLogger.monitorMsg
.get(msg);
if (MessageMonitorLogger.mMsgLoggerHandler.hasMessages(
MessageMonitorLogger.START_MONITOR_PENDING_TIMEOUT_MSG,
monitorMsg)){
Log.d("Looper", "Remove monitor msg= " + msg);
MessageMonitorLogger.mMsgLoggerHandler
.removeMessages(
MessageMonitorLogger.START_MONITOR_PENDING_TIMEOUT_MSG,
monitorMsg);
MessageMonitorLogger.monitorMsg.remove(msg);
}
}
}
mQueue.removeMessages(this, what, object);
}
// / MSG Logger Manager @}
/**
* 将message加入到队列
*/
private booleanenqueueMessage(MessageQueue queue, Message msg,
long uptimeMillis) {
msg.target = this;
if (mAsynchronous){
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
/**
* Remove any pending posts of messages withcode 'what' that are in the
* message queue.
*
* 移除所有挂起的拥有what值的message
*/
public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
}
/**
* Remove any pending posts of messages withcode 'what' and whose obj is
* 'object' that are in the message queue. If <var>object</var> is null, all
* messages will be removed.
*
* 同上,增加了object筛选
*/
public final void removeMessages(int what, Object object) {
mQueue.removeMessages(this, what, object);
}
/**
* Remove any pending posts of callbacks andsent messages whose
* <var>obj</var> is <var>token</var>. If <var>token</var> is null, all
* callbacks and messages will be removed.
*/
public final void removeCallbacksAndMessages(Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}
/**
* Check if there are any pending posts ofmessages with code 'what' in the
* message queue.
*
* 判断是否有what标识的message在队列里
*/
public final boolean hasMessages(int what) {
return mQueue.hasMessages(this, what, null);
}
/**
* Check if there are any pending posts ofmessages with code 'what' and
* whose obj is 'object' in the message queue.
*
* 同上,增加object
*/
public final boolean hasMessages(int what, Object object) {
return mQueue.hasMessages(this, what, object);
}
/**
* Check if there are any pending posts ofmessages with callback r in the
* message queue.
*
* @hide
*
* 判断队列里是否还有r
*/
public final boolean hasCallbacks(Runnable r) {
return mQueue.hasMessages(this, r, null);
}
// if we can get rid of this method, the handler need not remember itsloop
// we could instead export a getMessageQueue() method...
public finalLooper getLooper() {
return mLooper;
}
public final void dump(Printer pw, String prefix) {
pw.println(prefix+ this + " @ " + SystemClock.uptimeMillis());
if (mLooper== null){
pw.println(prefix+ "looper uninitialized");
}else {
mLooper.dump(pw, prefix + " ");
}
}
@Override
public String toString() {
return "Handler(" + getClass().getName() + ") {"
+Integer.toHexString(System.identityHashCode(this)) + "}";
}
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger!= null){
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
private final class MessengerImpl extends IMessenger.Stub {
public voidsend(Message msg) {
Handler.this.sendMessage(msg);
}
}
private staticMessage getPostMessage(Runnable r) {
Messagem = Message.obtain();
m.callback = r;
return m;
}
private staticMessage getPostMessage(Runnable r, Object token) {
Messagem = Message.obtain();
m.obj = token;
m.callback = r;
return m;
}
private static void handleCallback(Message message) {
message.callback.run();
}
final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;
final boolean mAsynchronous;
IMessengermMessenger;
private static final classBlockingRunnable implementsRunnable {
private finalRunnable mTask;
private boolean mDone;
public BlockingRunnable(Runnable task) {
mTask = task;
}
@Override
public voidrun() {
try {
mTask.run();
}finally {
synchronized (this) {
mDone = true;
notifyAll();
}
}
}
public booleanpostAndWait(Handler handler, longtimeout) {
if (!handler.post(this)) {
return false;
}
synchronized (this) {
if (timeout > 0) {
final longexpirationTime = SystemClock.uptimeMillis()
+timeout;
while (!mDone){
long delay = expirationTime
-SystemClock.uptimeMillis();
if (delay <= 0) {
return false;// timeout
}
try {
wait(delay);
}catch(InterruptedException ex) {
}
}
}else {
while (!mDone){
try {
wait();
}catch(InterruptedException ex) {
}
}
}
}
return true;
}
}
}