Handler mechanism (4) --- Handler source code parsing, handler --- handler

Source: Internet
Author: User

Handler mechanism (4) --- Handler source code parsing, handler --- handler

Handler has two main purposes: (1) to execute a message or a runnable at a certain time in the future, (2) to send a message to the message queue.

Mainly rely on post (Runnable), postAtTime (Runnable, long), postDelayed (Runnable, long), sendEmptyMessage (int), sendMessage (Message), sendMessageAtTime (Message), sendMessageDelayed (Message, long) to complete message scheduling. The post method inserts a Message into the Message queue when the Runable object arrives. The sendMessage method allows you to insert a Message containing information into the queue, and it will handle the handlerMessage (Message) of the Handler) (This method must be implemented in the subclass of Handler ).

1. Constructor
/** Default constructor: handler is associated with the queue of the current thread. If the queue does not exist, handler cannot accept messages. * Default constructor associates this handler with the {@ link Looper} for the * current thread. * If the thread does not have a logoff, an exception will be thrown. * If this thread does not have a logoff, this handler won't be able to receive messages * so an exception is thrown. */public Handler () {this (null, false);} // input a callback interface to process the Message passed by handler. Public Handler (Callback callback) {this (callback, false);} // assign the 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 shocould be static or leaks might occur:" + klass. getCanonicalName () ;}} mLooper = Looper. myLooper (); if (mloexception = null) {throw new RuntimeException ("Can't create handler inside thread that has not called loled. prepare () ");} mQueue = mloue. mQueue; mCallback = callback; mAsynchronous = async;} public Handler (Looper loler, Callback callback, boolean async) {mloler = loler; mQueue = looper. mQueue; mCallback = callback; mAsynchronous = async ;}

Methods are almost the same, mainly to complete the assignment process, there are a few not pasted, but almost all...

2. Variables
/* Set this flag to true to detect non-static anonymity. Local or member classes inherit the Handler class. These types of classes can cause potential leakage. This parameter is used in the Handler constructor for the purpose described above. */Private static final boolean FIND_POTENTIAL_LEAKS = false; final MessageQueue mQueue; final Looper mloue; final Callback mCallback; // Callback interface final boolean mAsynchronous; IMessenger mmesaks;

The following is the Callback interface:

/*** Callback interface you can use when instantiating (instantiation) a Handler to avoid * having to implement (Implementation) your own subclass of Handler. * @ param msg A {@ link android. OS. message} object * @ return True if no further handling is desired */public interface Callback {public boolean handleMessage (Message msg );}

You can use the callback interface during Instantiation to avoid implementing your own handler subclass.

Only one handleMessage method in this Callback interface returns a boolean value, which will be used by the Handler ctor later. Generally, it is null. This interface exists

There is no special meaning, just to enable you to process messages without using extends Handler (as described in the doc in this method), similar to the relationship between Thread and Runnable interfaces.

3. handleMessage
/**     * Subclasses must implement this to receive messages.     */    public void handleMessage(Message msg) {    }

Subclass needs to implement this method, because this is an empty method.

4. 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);        }    }private static void handleCallback(Message message) {        message.callback.run();    }

If callback is set for the message

Call the callback. run () method directly. Otherwise, the Callback interface will become effective. If we pass the implementation of the Callback interface, that is, mCallback is not empty, call it for processing.

Message. If yes, return true. Otherwise, call the handleMessage method of Handler. The default implementation is do nothing.

It is extends Handler, so you should provide your own implementation for handleMessage in your subclass.

5. A series of obtainmessages
public final Message obtainMessage()    {        return Message.obtain(this);    }public final Message obtainMessage(int what)    {        return Message.obtain(this, what);    }public final Message obtainMessage(int what, int arg1, int arg2, Object obj)    {        return Message.obtain(this, what, arg1, arg2, obj);    }

We can see from the above that the obtain method of the Message is called to construct the message.

6. A series of postXXX methods:
 /**     * 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);    }public final boolean postAtTime(Runnable r, long uptimeMillis)    {        return sendMessageAtTime(getPostMessage(r), uptimeMillis);    } public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)    {        return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);    }public final boolean postDelayed(Runnable r, long delayMillis)    {        return sendMessageDelayed(getPostMessage(r), delayMillis);    } public final boolean postAtFrontOfQueue(Runnable r)    {        return sendMessageAtFrontOfQueue(getPostMessage(r));    }

The preceding method is used to send Runnable to the message queue and run Runnable during execution ..

The following describes a series of sendXXX methods, which correspond to the above...

// Set the Message to public final boolean sendMessageDelayed (Message msg, long delayMillis) {if (delayMillis <0) {delayMillis = 0;} return sendMessageAtTime (msg, SystemClock. uptimeMillis () + delayMillis);} 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 ("logoff", e. getMessage (), e); return false;} return enqueueMessage (queue, msg, uptimeMillis);} public final boolean sendEmptyMessage (int what) {return sendEmptyMessageDelayed (what, 0 );

All postXXX and sendXXX methods above will call this method at last: enqueueMessage

 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {        msg.target = this;        if (mAsynchronous) {            msg.setAsynchronous(true);        }        return queue.enqueueMessage(msg, uptimeMillis);    }

Finally, call the queue's enqueueMessage method to queue the msg. If you do not know this method, you can check the MessageQueue source code parsing at the front.

SystemClock. uptimeMillis () indicates the total number of times the system is started to the current time. If there is a delay, plus the delay time, we can also find that postDelayed is not the delay of how many seconds to send messages, this message is sent directly to the queue. However, in the MessaegQueue, the message is discharged by time and will not be retrieved in time. Therefore, it should be said that it is more appropriate to retrieve the message in seconds after the delay ..

As for the above getPostMessage (r), the r is set to callback.

private static Message getPostMessage(Runnable r) {        Message m = Message.obtain();        m.callback = r;        return m;    }
RemoveCallbacks:

Call the removeMessages method of MQ. It is to remove all the messages that meet the conditions in messageQueue. Of course, the premise is that the message has not been removed.

  /**     * 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 <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.     */    public final void removeCallbacks(Runnable r, Object token)    {        mQueue.removeMessages(this, r, token);    }

The analysis is over. Encourage yourself to proceed .. Haha ....

The first three portals: logoff source code analysis: http://www.cnblogs.com/jycboy/p/5787443.html

MessageQueue source code analysis: http://www.cnblogs.com/jycboy/p/5786682.html

Message source code analysis: http://www.cnblogs.com/jycboy/p/5786551.html

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.