Handler mechanism (1) --- Message source code analysis, handler --- message

Source: Internet
Author: User

Handler mechanism (1) --- Message source code analysis, handler --- message
Message:

Definition:

public final class Message implements Parcelable 

The Message class is a final class, that is, it cannot be inherited. At the same time, the Message class implements the Parcelable interface. We know that android provides a new type: Parcel.This class is used as a container to encapsulate data. It is a linked list structure,There is an attribute "next" and "sPool". The two variables are different. For details, see the following.

Description:

Defines a message containing a description and arbitrary data object that can be sent to a {@link Handler}.  This object contains two extra int fields and an extra object field that allow you to not do allocations in many cases.  

Define a descriptive data object containing any type, which can be sent to Handler. The object contains two additional int fields and one additional object field, so that allocation is not required in many cases. Although the Message constructor is public, the best way to get the Message object is to call Message. obtain () or Handler. obtainMessage (). In this way, the Message object is obtained from a recycle Object pool.

1. Take a look at global variables: There are many objects storing data.
public int what;public int arg1; public int arg2;public Object obj;public Messenger replyTo;/*package*/ int flags;/*package*/ long when;/*package*/ Bundle data;/*package*/ Handler target;/*package*/ Runnable callback;// sometimes we store linked lists of these things/*package*/ Message next;private static final Object sPoolSync = new Object();private static Message sPool;private static int sPoolSize = 0;private static final int MAX_POOL_SIZE = 50;private static boolean gCheckRecycle = true;
Obtain method:

 

// Return a new Message instance from the global pool. In most cases, this avoids the allocation of new objects. // Is a static method public static Message obtain () {synchronized (sPoolSync) {if (sPool! = Null) {Message m = sPool; sPool = m. next; m. next = null; m. flags = 0; // clear in-use flag sPoolSize --; return m ;}} return new Message ();}

Looking at its series of overload methods:

/*** Same as {@ link # obtain ()}, but copies the values of an existing * message (including its target) into the new one. * @ param orig Original message to copy. * @ return A Message object from the global pool. */public static Message obtain (Message orig) {Message m = obtain (); m. what = orig. what; m. arg1 = orig. arg1; m. arg2 = orig. arg2; m. obj = orig. obj; m. replyTo = orig. replyTo; m. sendingUid = ori G. sendingUid; if (orig. data! = Null) {m. data = new Bundle (orig. data);} m.tar get = orig.tar get; m. callback = orig. callback; return m;}/** set target */public static Message obtain (Handler h) {Message m = obtain (); m.tar get = h; return m ;} /*** Same as {@ link # obtain (Handler)}, but assigns a callback Runnable on * the Message that is returned. * @ param h Handler to assign to the returned Message object's <em> target </em> mem Ber. * @ param callback Runnable that will execute when the message is handled. * @ return A Message object from the global pool. */public static Message obtain (Handler h, Runnable callback) {Message m = obtain (); m.tar get = h; m. callback = callback; return m;}/*** Same as {@ link # obtain ()}, but sets the values of the <em> target </em>, <em> what </em>, * <em> arg1 </em>, <em> arg2 </em>, and <em> obj </e M> members ..... * @ Param obj The <em> obj </em> value to set. * @ return A Message object from the global pool. */public static Message obtain (Handler h, int what, int arg1, int arg2, Object obj) {Message m = obtain (); m.tar get = h; m. what = what; m. arg1 = arg1; m. arg2 = arg2; m. obj = obj; return m ;}

Several other parameters are not listed. The obtain () method is called first, and various parameters are added to the obtained Message instance. Code at a glance...

Recycle (): recycles the current message to the global pool.

 

/**     * Return a Message instance to the global pool.     * <p>     * You MUST NOT touch the Message after calling this function because it has     * effectively been freed.  It is an error to recycle a message that is currently     * enqueued or that is in the process of being delivered to a Handler.     * </p>     */    public void recycle() {        if (isInUse()) {            if (gCheckRecycle) {                throw new IllegalStateException("This message cannot be recycled because it "                        + "is still in use.");            }            return;        }        recycleUnchecked();    }    /**     * Recycles a Message that may be in-use.     * Used internally by the MessageQueue and Looper when disposing of queued Messages.     */    void recycleUnchecked() {        // Mark the message as in use while it remains in the recycled object pool.        // Clear out all other details.        flags = FLAG_IN_USE;        what = 0;        arg1 = 0;        arg2 = 0;        obj = null;        replyTo = null;        sendingUid = -1;        when = 0;        target = null;        callback = null;        data = null;        synchronized (sPoolSync) {            if (sPoolSize < MAX_POOL_SIZE) {                next = sPool;                sPool = this;                sPoolSize++;            }        }    }

Returns a Message instance to the global pool. You must not use Message after calling this function -- it is actually released.

GetWhen:

 /**     * Return the targeted delivery time of this message, in milliseconds.     */    public long getWhen() {        return when;    }

The transmission time of the message, in milliseconds.

 

SetTarget, getTarget:

// Set handler and return handlerpublic void setTarget (Handler target) {this.tar get = target;}/*** Retrieve the {@ link android. OS. handler} implementation that * will receive this message. the object must implement * {@ link android. OS. handler # handleMessage (android. OS. message) * Handler. handleMessage ()}. each Handler has its own name-space for * message codes, so you do not need to * worry about yours conflicting with other handlers. */public Handler getTarget () {return target ;}

Gets the Handler object that will receive the message. This object must implement the Handler. handleMessage () method. Each handler contains its own message code, so you don't have to worry about conflicts between custom messages and other handlers.

SetData:

Set a bundle that can be of any type.

/**     * Sets a Bundle of arbitrary data values. Use arg1 and arg2 members     * as a lower cost way to send a few simple integer values, if you can.     * @see #getData()      * @see #peekData()     */    public void setData(Bundle data) {        this.data = data;    }

GetData, peekData

 public Bundle getData() {        if (data == null) {            data = new Bundle();        }                return data;    }public Bundle peekData() {        return data;}
Some methods for sending messages:
/** Send this message to Handler. The getTarget () method can obtain this Handler. If this field is not set, a null pointer exception is thrown. * Sends this Message to the Handler specified by {@ link # getTarget }. * Throws a null pointer exception if this field has not been set. */public void sendToTarget () {target. sendMessage (this );}
Constructor:
/** Constructor (but the preferred way to get a Message is to call {@ link # obtain () Message. obtain ()}). */public Message () {}// Message is recommended. obtain ()
WriteToParcel:
public void writeToParcel(Parcel dest, int flags) {        if (callback != null) {            throw new RuntimeException(                "Can't marshal callbacks across processes.");        }        dest.writeInt(what);        dest.writeInt(arg1);        dest.writeInt(arg2);        if (obj != null) {            try {                Parcelable p = (Parcelable)obj;                dest.writeInt(1);                dest.writeParcelable(p, flags);            } catch (ClassCastException e) {                throw new RuntimeException(                    "Can't marshal non-Parcelable objects across processes.");            }        } else {            dest.writeInt(0);        }        dest.writeLong(when);        dest.writeBundle(data);        Messenger.writeMessengerOrNullToParcel(replyTo, dest);        dest.writeInt(sendingUid);    }

Write the data of the class to the external provided Parcel and read the data from Parcel.

Message ended ....

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.