简单说一下谷歌的Message以及常用的方法

来源:互联网 发布:爱普生lq610k打印端口 编辑:程序博客网 时间:2024/04/29 18:45

先看一下谷歌的源码

/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.os;import android.util.TimeUtils;/** *  * 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.   * * <p class="note">While the constructor of Message is public, the best way to get * one of these is to call {@link #obtain Message.obtain()} or one of the * {@link Handler#obtainMessage Handler.obtainMessage()} methods, which will pull * them from a pool of recycled objects.</p> */public final class Message implements Parcelable {    /**     * User-defined message code so that the recipient can identify      * what this message is about. Each {@link Handler} has its own name-space     * for message codes, so you do not need to worry about yours conflicting     * with other handlers.     */    public int what;    /**     * arg1 and arg2 are lower-cost alternatives to using     * {@link #setData(Bundle) setData()} if you only need to store a     * few integer values.     */    public int arg1;     /**     * arg1 and arg2 are lower-cost alternatives to using     * {@link #setData(Bundle) setData()} if you only need to store a     * few integer values.     */    public int arg2;    /**     * An arbitrary object to send to the recipient.  When using     * {@link Messenger} to send the message across processes this can only     * be non-null if it contains a Parcelable of a framework class (not one     * implemented by the application).   For other data transfer use     * {@link #setData}.     *      * <p>Note that Parcelable objects here are not supported prior to     * the {@link android.os.Build.VERSION_CODES#FROYO} release.     */    public Object obj;    /**     * Optional Messenger where replies to this message can be sent.  The     * semantics of exactly how this is used are up to the sender and     * receiver.     */    public Messenger replyTo;    /** If set message is in use */    /*package*/ static final int FLAG_IN_USE = 1 << 0;    /** If set message is asynchronous */    /*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1;    /** Flags to clear in the copyFrom method */    /*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE;    /*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;    /**     * Return a new Message instance from the global pool. Allows us to     * avoid allocating new objects in many cases.     */    public static Message obtain() {        synchronized (sPoolSync) {            if (sPool != null) {                Message m = sPool;                sPool = m.next;                m.next = null;                sPoolSize--;                return m;            }        }        return new Message();    }    /**     * 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;        if (orig.data != null) {            m.data = new Bundle(orig.data);        }        m.target = orig.target;        m.callback = orig.callback;        return m;    }    /**     * Same as {@link #obtain()}, but sets the value for the <em>target</em> member on the Message returned.     * @param h  Handler to assign to the returned Message object's <em>target</em> member.     * @return A Message object from the global pool.     */    public static Message obtain(Handler h) {        Message m = obtain();        m.target = 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> member.     * @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.target = h;        m.callback = callback;        return m;    }    /**     * Same as {@link #obtain()}, but sets the values for both <em>target</em> and     * <em>what</em> members on the Message.     * @param h  Value to assign to the <em>target</em> member.     * @param what  Value to assign to the <em>what</em> member.     * @return A Message object from the global pool.     */    public static Message obtain(Handler h, int what) {        Message m = obtain();        m.target = h;        m.what = what;        return m;    }    /**     * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, and <em>obj</em>     * members.     * @param h  The <em>target</em> value to set.     * @param what  The <em>what</em> value to set.     * @param obj  The <em>object</em> method to set.     * @return  A Message object from the global pool.     */    public static Message obtain(Handler h, int what, Object obj) {        Message m = obtain();        m.target = h;        m.what = what;        m.obj = obj;        return m;    }    /**     * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,      * <em>arg1</em>, and <em>arg2</em> members.     *      * @param h  The <em>target</em> value to set.     * @param what  The <em>what</em> value to set.     * @param arg1  The <em>arg1</em> value to set.     * @param arg2  The <em>arg2</em> value to set.     * @return  A Message object from the global pool.     */    public static Message obtain(Handler h, int what, int arg1, int arg2) {        Message m = obtain();        m.target = h;        m.what = what;        m.arg1 = arg1;        m.arg2 = arg2;        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</em> members.     *      * @param h  The <em>target</em> value to set.     * @param what  The <em>what</em> value to set.     * @param arg1  The <em>arg1</em> value to set.     * @param arg2  The <em>arg2</em> value to set.     * @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.target = h;        m.what = what;        m.arg1 = arg1;        m.arg2 = arg2;        m.obj = obj;        return m;    }    /**     * Return a Message instance to the global pool.  You MUST NOT touch     * the Message after calling this function -- it has effectively been     * freed.     */    public void recycle() {        clearForRecycle();        synchronized (sPoolSync) {            if (sPoolSize < MAX_POOL_SIZE) {                next = sPool;                sPool = this;                sPoolSize++;            }        }    }    /**     * Make this message like o.  Performs a shallow copy of the data field.     * Does not copy the linked list fields, nor the timestamp or     * target/callback of the original message.     */    public void copyFrom(Message o) {        this.flags = o.flags & ~FLAGS_TO_CLEAR_ON_COPY_FROM;        this.what = o.what;        this.arg1 = o.arg1;        this.arg2 = o.arg2;        this.obj = o.obj;        this.replyTo = o.replyTo;        if (o.data != null) {            this.data = (Bundle) o.data.clone();        } else {            this.data = null;        }    }    /**     * Return the targeted delivery time of this message, in milliseconds.     */    public long getWhen() {        return when;    }        public void setTarget(Handler target) {        this.target = target;    }    /**     * Retrieve the a {@link android.os.Handler 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;    }    /**     * Retrieve callback object that will execute when this message is handled.     * This object must implement Runnable. This is called by     * the <em>target</em> {@link Handler} that is receiving this Message to     * dispatch it.  If     * not set, the message will be dispatched to the receiving Handler's     * {@link Handler#handleMessage(Message Handler.handleMessage())}.     */    public Runnable getCallback() {        return callback;    }        /**      * Obtains a Bundle of arbitrary data associated with this     * event, lazily creating it if necessary. Set this value by calling     * {@link #setData(Bundle)}.  Note that when transferring data across     * processes via {@link Messenger}, you will need to set your ClassLoader     * on the Bundle via {@link Bundle#setClassLoader(ClassLoader)     * Bundle.setClassLoader()} so that it can instantiate your objects when     * you retrieve them.     * @see #peekData()     * @see #setData(Bundle)     */    public Bundle getData() {        if (data == null) {            data = new Bundle();        }                return data;    }    /**      * Like getData(), but does not lazily create the Bundle.  A null     * is returned if the Bundle does not already exist.  See     * {@link #getData} for further information on this.     * @see #getData()     * @see #setData(Bundle)     */    public Bundle peekData() {        return data;    }    /**     * Sets a Bundle of arbitrary data values. Use arg1 and arg1 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;    }    /**     * 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);    }    /**     * Returns true if the message is asynchronous.     *     * Asynchronous messages represent interrupts or events that do not require global ordering     * with represent to synchronous messages.  Asynchronous messages are not subject to     * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.     *     * @return True if the message is asynchronous.     *     * @see #setAsynchronous(boolean)     * @see MessageQueue#enqueueSyncBarrier(long)     * @see MessageQueue#removeSyncBarrier(int)     *     * @hide     */    public boolean isAsynchronous() {        return (flags & FLAG_ASYNCHRONOUS) != 0;    }    /**     * Sets whether the message is asynchronous.     *     * Asynchronous messages represent interrupts or events that do not require global ordering     * with represent to synchronous messages.  Asynchronous messages are not subject to     * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.     *     * @param async True if the message is asynchronous.     *     * @see #isAsynchronous()     * @see MessageQueue#enqueueSyncBarrier(long)     * @see MessageQueue#removeSyncBarrier(int)     *     * @hide     */    public void setAsynchronous(boolean async) {        if (async) {            flags |= FLAG_ASYNCHRONOUS;        } else {            flags &= ~FLAG_ASYNCHRONOUS;        }    }    /*package*/ void clearForRecycle() {        flags = 0;        what = 0;        arg1 = 0;        arg2 = 0;        obj = null;        replyTo = null;        when = 0;        target = null;        callback = null;        data = null;    }    /*package*/ boolean isInUse() {        return ((flags & FLAG_IN_USE) == FLAG_IN_USE);    }    /*package*/ void markInUse() {        flags |= FLAG_IN_USE;    }    /** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}).    */    public Message() {    }    @Override    public String toString() {        return toString(SystemClock.uptimeMillis());    }    String toString(long now) {        StringBuilder b = new StringBuilder();        b.append("{ when=");        TimeUtils.formatDuration(when - now, b);        if (target != null) {            if (callback != null) {                b.append(" callback=");                b.append(callback.getClass().getName());            } else {                b.append(" what=");                b.append(what);            }            if (arg1 != 0) {                b.append(" arg1=");                b.append(arg1);            }            if (arg2 != 0) {                b.append(" arg2=");                b.append(arg2);            }            if (obj != null) {                b.append(" obj=");                b.append(obj);            }            b.append(" target=");            b.append(target.getClass().getName());        } else {            b.append(" barrier=");            b.append(arg1);        }        b.append(" }");        return b.toString();    }    public static final Parcelable.Creator<Message> CREATOR            = new Parcelable.Creator<Message>() {        public Message createFromParcel(Parcel source) {            Message msg = Message.obtain();            msg.readFromParcel(source);            return msg;        }                public Message[] newArray(int size) {            return new Message[size];        }    };            public int describeContents() {        return 0;    }    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);    }    private void readFromParcel(Parcel source) {        what = source.readInt();        arg1 = source.readInt();        arg2 = source.readInt();        if (source.readInt() != 0) {            obj = source.readParcelable(getClass().getClassLoader());        }        when = source.readLong();        data = source.readBundle();        replyTo = Messenger.readMessengerOrNullFromParcel(source);    }}

它去实现了一个叫parcelable的接口,messenger也是实现了这个接口,先看message最后看那个接口

首先,定义了了也是咱们经常用的what,arg1,arg2,还有obj,前三个是int类型,最后一个是obj类型的,一般的话前三个和bundle就够用了

还有就是使用message的时候,如果不注意或者不去考虑效率的话初级的写法有可能会new而不是obtain,但是这样做不好,其实使用它的obtain最好了,可以根据实际需求进行重载,一般的话我使用的是空参数的obtain,可以简单理解为每次都是把顶部的message取出来复制再去进行send。

再有就是常用的setdata和getdata,这个的话是结合bundle使用的,可以携带大量的数据,还有几个这没有说,大家可以去研究下

0 0