惯例,先来看一下,google对于Handler类的解释

/** * A Handler allows you to send and process {@link Message} and Runnable * objects associated with a thread's {@link MessageQueue}.  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 that point on, * it will deliver messages and runnables to 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 to be executed as some point in the future; and (2) to enqueue * an action to be performed 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 to enqueue 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 that will 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 to * running 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. */public class Handler {......}

Handler类允许发送和处理和线程相关的消息池中的Message和Runnable对象,每一个Handler对象都和一个线程和这个线程对应的消息池相关联,当创建一个Handler对象的时候,会自动和其对应的线程和消息池绑定,它会传递messages和runnables到消息池中,同时处理从消息池中获取到的消息

它有两个主要的用法:1)插入消息时,有序存放消息到消息池,以便于后续执行 2)to enqueue an action to be performed on a different thread than your own.

那么我们就先看看它的post系列方法

/**     * Causes the Runnable r to be added to the message queue.     * The runnable will be run on the thread to which this handler is      * 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.     */    public final boolean post(Runnable r)    {       return  sendMessageDelayed(getPostMessage(r), 0);    }
传入一个Runnable对象,调用了其的sendMEssageDElayed方法

先来看看getPostMessage(r)方法中做了什么

private static Message getPostMessage(Runnable r) {        Message m = Message.obtain();        m.callback = r;        return m;    }
private static Message getPostMessage(Runnable r, Object token) {        Message m = Message.obtain();        m.obj = token;        m.callback = r;        return m;    }
如Message中的解释,创建一个Message对象,并赋予相应的值

再来看看其他的post方法

/**     * Causes the Runnable r to be added to the message queue, to be run     * at a specific time given by uptimeMillis.     * The time-base is {@link android.os.SystemClock#uptimeMillis}.     * Time spent in deep sleep will add an additional delay to execution.     * The runnable will be run on the thread to which this handler is attached.     *     * @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.     */    public final boolean postAtTime(Runnable r, long uptimeMillis)    {        return sendMessageAtTime(getPostMessage(r), uptimeMillis);    }
/**     * Causes the Runnable r to be added to the message queue, to be run     * at a specific time given by uptimeMillis.     * The time-base is {@link android.os.SystemClock#uptimeMillis}.     * Time spent in deep sleep will add an additional delay to execution.     * The runnable will be run on the thread to which this handler is attached.     *     * @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     */    public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)    {        return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);    }
/**     * Causes the Runnable r to be added to the message queue, to be run     * after the specified amount of time elapses.     * The runnable will be run on the thread to which this handler     * is attached.     * The time-base is {@link android.os.SystemClock#uptimeMillis}.     * Time spent in deep sleep will add an additional delay to execution.     *       * @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.     */    public final boolean postDelayed(Runnable r, long delayMillis)    {        return sendMessageDelayed(getPostMessage(r), delayMillis);    }
/**     * Posts a message to an object that implements Runnable.     * Causes the Runnable r to executed on the next iteration through the     * message queue. The runnable will be run on the thread to which this     * handler is attached.     * This method is only for use in very special circumstances -- it     * can easily starve the message queue, cause ordering problems, or have     * other unexpected side-effects.     *       * @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.     */    public final boolean postAtFrontOfQueue(Runnable r)    {        return sendMessageAtFrontOfQueue(getPostMessage(r));    }
均调用了Handler的sendMessage系列方法,sendMessage系列方法,恐怕是我们都很常用的系列方法吧,接下来看

 /**     * Pushes a message onto the end of the message queue after all pending messages     * before the current time. It will be received 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.     */    public final boolean sendMessage(Message msg)    {        return sendMessageDelayed(msg, 0);    }
/**     * Enqueue a message into the message queue after all pending messages     * before (current time + delayMillis). You will 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.     */    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 queue after all pending messages     * before the absolute time (in milliseconds) uptimeMillis.     * The time-base is {@link android.os.SystemClock#uptimeMillis}.     * Time spent in deep sleep will add an additional delay to execution.     * You will receive it in {@link #handleMessage}, in the thread 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.     */    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {        MessageQueue queue = mQueue;        if (queue == null) {            RuntimeException e = new RuntimeException(                    this + " sendMessageAtTime() called with no mQueue");            Log.w("Looper", e.getMessage(), e);            return false;        }        return enqueueMessage(queue, msg, uptimeMillis);    }
最终调用的是Handler的enqueueMessage方法,这个方法我们稍后再看,sendMessage系列还有些其他的方法

/**     * Sends a Message containing only the what value.     *       * @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 sendEmptyMessage(int what)    {        return sendEmptyMessageDelayed(what, 0);    }
/**     * Sends a Message containing only the what value, 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.     */    public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {        Message msg = Message.obtain();        msg.what = what;        return sendMessageDelayed(msg, delayMillis);    }
依旧调用的是sendMessageDelayed方法,最后回到enqueueMessage方法了

/**     * Sends a Message containing only the what value, 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) {        Message msg = Message.obtain();        msg.what = what;        return sendMessageAtTime(msg, uptimeMillis);    }
/**     * Enqueue a message at the front of the message queue, to be processed on     * the next iteration of the message loop.  You will receive it in     * {@link #handleMessage}, in the thread attached to this handler.     * This method is only for use in very special circumstances -- it     * can easily starve the message queue, cause ordering problems, or have     * other unexpected side-effects.     *       * @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) {        MessageQueue queue = mQueue;        if (queue == null) {            RuntimeException e = new RuntimeException(                this + " sendMessageAtTime() called with no mQueue");            Log.w("Looper", e.getMessage(), e);            return false;        }        return enqueueMessage(queue, msg, 0);    }
好了,这些sendMessage系列的方法最终都是调用了enqueueMessage方法,所以,接下来看看

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {        msg.target = this;        if (mAsynchronous) {            msg.setAsynchronous(true);        }        return queue.enqueueMessage(msg, uptimeMillis);    }
这个方法中,将当前的Handler对象设置给了msg的target参数,最后,将消息加入到消息队列中了。

还记得Looper的loop方法,死循环处理消息,调用msg.target.dispatchMessage(msg);方法处理消息的,所以直接进入Handler的dispatchMessage方法

/**     * Handle system messages here.     */    public void dispatchMessage(Message msg) {        if (msg.callback != null) {            handleCallback(msg);        } else {            if (mCallback != null) {                if (mCallback.handleMessage(msg)) {                    return;                }            }            handleMessage(msg);        }    }
从这个方法中,我们看到,先判断msg.callback是否为null,若不为null,之调用handleCallback方法,那么msg.callback是什么?它是我们传入的Runnable对象,还记得Handler的post系列方法中,有些我们传入的有Runnable对象,有些没有,因此此地有两种方式处理

private static void handleCallback(Message message) {    // 直接运行Runnable对象的run方法    message.callback.run();    }

若未传入Runnbale对象,则走else方式,就调用了我们在新建Handler对象时,重写的handleMessage方法了

接下来,我们继续看看Handler的其他方法

首先Handler的构造函数

/**     * Default constructor associates this handler with the {@link Looper} for the     * current thread.     *     * If this thread does not have a looper, this handler won't be able to receive messages     * so an exception is thrown.     */    public Handler() {        this(null, false);    }
/**     * Constructor associates this handler with the {@link Looper} for the     * current thread and takes a callback interface in which you can handle     * messages.     *     * If this thread does not have a looper, this handler won't be able to receive messages     * so an exception is thrown.     *     * @param callback The callback interface in which to handle messages, or 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.     */    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 handle messages.     *     * @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 the handler should be asynchronous.     *     * Handlers are synchronous by default unless this constructor is used to make     * one that is strictly asynchronous.     *     * Asynchronous messages represent interrupts or events that do not require global ordering     * with respect to synchronous messages.  Asynchronous messages are not subject to     * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.     *     * @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(boolean async) {        this(null, async);    }
/**     * Use the {@link Looper} for the current thread with the specified callback interface     * and set whether the handler should be asynchronous.     *     * Handlers are synchronous by default unless this constructor is used to make     * one that is strictly asynchronous.     *     * Asynchronous messages represent interrupts or events that do not require global ordering     * with respect to synchronous messages.  Asynchronous messages are not subject to     * the synchronization barriers introduced by {@link MessageQueue#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) {    // Leo, 直接是false,无法进入运行,跳过        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 new RuntimeException(                "Can't create handler inside thread that has not called Looper.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 handle messages.  Also set whether the handler     * should be asynchronous.     *     * Handlers are synchronous by default unless this constructor is used to make     * one that is strictly asynchronous.     *     * Asynchronous messages represent interrupts or events that do not require global ordering     * with respect to synchronous messages.  Asynchronous messages are not subject to     * the synchronization barriers introduced by {@link MessageQueue#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 {@link Runnable} that is posted to it.     *     * @hide     */    public Handler(Looper looper, Callback callback, boolean async) {        mLooper = looper;        mQueue = looper.mQueue;        mCallback = callback;        mAsynchronous = async;    }
定义一些参数的值,mLooper,mQueue,mCallback和mAsynvhronous

/**     * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than     * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).     *  If you don't want that facility, just call Message.obtain() instead.     */    public final Message obtainMessage()    {        return Message.obtain(this);    }
/**     * Same as {@link #obtainMessage()}, except that it 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.     */    public final Message obtainMessage(int what)    {        return Message.obtain(this, what);    }
/**     *      * Same as {@link #obtainMessage()}, except that it 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.     */    public final Message obtainMessage(int what, Object obj)    {        return Message.obtain(this, what, obj);    }
/**     *      * Same as {@link #obtainMessage()}, except that it 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.     */    public final Message obtainMessage(int what, int arg1, int arg2)    {        return Message.obtain(this, what, arg1, arg2);    }
/**     *      * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on 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.     * @param obj Value to assign to the returned Message.obj field.     * @return A Message from the global message pool.     */    public final Message obtainMessage(int what, int arg1, int arg2, Object obj)    {        return Message.obtain(this, what, arg1, arg2, obj);    }
obtain系列方法,具体可见Message的obtain方法,返回Message对象

/**     * Remove any pending posts of Runnable r that are in the message queue.     */    public final void removeCallbacks(Runnable r)    {        mQueue.removeMessages(this, r, null);    }
/**     * Remove any pending posts of Runnable r with Object     * token that are in the message queue.  If token is null,     * all callbacks will be removed.     */    public final void removeCallbacks(Runnable r, Object token)    {        mQueue.removeMessages(this, r, token);    }
将消息从消息队列中移除

/**     * Remove any pending posts of messages with code 'what' that are in the     * message queue.     */    public final void removeMessages(int what) {        mQueue.removeMessages(this, what, null);    }
/**     * Remove any pending posts of messages with code 'what' and whose obj is     * 'object' that are in the message queue.  If object is null,     * all messages will be removed.     */    public final void removeMessages(int what, Object object) {        mQueue.removeMessages(this, what, object);    }
/**     * Remove any pending posts of callbacks and sent messages whose     * obj is token.  If token 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 of messages with code 'what' in     * the message queue.     */    public final boolean hasMessages(int what) {        return mQueue.hasMessages(this, what, null);    }
/**     * Check if there are any pending posts of messages with code 'what' and     * whose obj is 'object' in the message queue.     */    public final boolean hasMessages(int what, Object object) {        return mQueue.hasMessages(this, what, object);    }
/**     * Check if there are any pending posts of messages with callback r in     * the message queue.     *      * @hide     */    public final boolean hasCallbacks(Runnable r) {        return mQueue.hasMessages(this, r, null);    }
判断消息队列中是否已有指定消息

private static Message getPostMessage(Runnable r) {        Message m = Message.obtain();        m.callback = r;        return m;    }
private static Message getPostMessage(Runnable r, Object token) {        Message m = Message.obtain();        m.obj = token;        m.callback = r;        return m;    }
获取消息对象

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. 类和 Json对象
  3. Python list sort方法的具体使用
  4. python list.sort()根据多个关键字排序的方法实现
  5. android上一些方法的区别和用法的注意事项
  6. android实现字体闪烁动画的方法
  7. Android中dispatchDraw分析
  8. 浅析Android中的消息机制-解决:Only the original thread that cr
  9. Android四大基本组件介绍与生命周期

随机推荐

  1. Android 富文本编辑器RichEdit,完整demo
  2. 《Android安全机制解析与应用实践》笔记
  3. Android 进程保活招式大全(转)
  4. 移植 C/C++ 代码至 Android 平台经验总结
  5. Android开发者不可或缺的四大工具
  6. Android线程模型
  7. Handler完全重新理解
  8. Study on Android【五】--自定义ContentP
  9. android sdk 安装更新慢:下载android sdk
  10. 配置Vim开发Android详解