(M)Android消息处理机制分析之Message类解析
来源:互联网 发布:美工设计班 编辑:程序博客网 时间:2024/06/16 09:21
首先,我们查看一下Google 对于 Message类的备注
/** * * 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 {......}意思是,定义一个包含一个描述和任何类型数据的消息,可以被发送到Handler。这个任意类型数据包括了两个额外int型数据和一个额外的Object类型的数据,以便我们在许多情况下不需要分配空间。尽管Message的构造函数是public的,最好的方式还是通过调用Message的obtain方法或者Handler的obtainMessage方法来定义一个Message,这是因为这样会从一个再循环的(消息)池中取出它们。(只是自己的翻译,也许翻译不准确)
既然如此,我们就先看看Message的obtain方法中究竟做了什么?
/** * 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; m.flags = 0; // clear in-use flag sPoolSize--; return m; } } return new Message(); }sPool是一个Message对象,当sPool不为null的时候,就会直接返回sPool的对象,而不重新申请空间,而当sPool为null的时候,我们才会通过new的方式,向系统申请空间,因此,调用obtain方法的时候,会节约很多空间
/** * 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 = orig.sendingUid; 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; }Message中提供了很多obtain方法,方便用户在创建Message的时候调用。
/** * 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++; } } }从方法名称上来看,这两个方法应该是回收Message,但是在这个类中,没有被回收,直接将flags职位FLAG_IN_USE,这就为obtain方法提供了可能。
/** * 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; this.sendingUid = o.sendingUid; if (o.data != null) { this.data = (Bundle) o.data.clone(); } else { this.data = null; } }从其他Message中拷贝一份一样的消息数据
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; }需要注意,Message对象中的target是Handler对象
/** * 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; }这个类中的callback是Runnable对象
/** * 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); }这个方法是我们常用的,但是需要注意,调用这个方法的时候,一定要先设定其的target参数
/** * Returns true if the message is asynchronous, meaning that it is not * subject to {@link Looper} synchronization barriers. * * @return True if the message is asynchronous. * * @see #setAsynchronous(boolean) */ public boolean isAsynchronous() { return (flags & FLAG_ASYNCHRONOUS) != 0; }消息是否是异步
/** * Sets whether the message is asynchronous, meaning that it is not * subject to {@link Looper} synchronization barriers. * <p> * Certain operations, such as view invalidation, may introduce synchronization * barriers into the {@link Looper}'s message queue to prevent subsequent messages * from being delivered until some condition is met. In the case of view invalidation, * messages which are posted after a call to {@link android.view.View#invalidate} * are suspended by means of a synchronization barrier until the next frame is * ready to be drawn. The synchronization barrier ensures that the invalidation * request is completely handled before resuming. * </p><p> * Asynchronous messages are exempt from synchronization barriers. They typically * represent interrupts, input events, and other signals that must be handled independently * even while other work has been suspended. * </p><p> * Note that asynchronous messages may be delivered out of order with respect to * synchronous messages although they are always delivered in order among themselves. * If the relative order of these messages matters then they probably should not be * asynchronous in the first place. Use with caution. * </p> * * @param async True if the message is asynchronous. * * @see #isAsynchronous() */ public void setAsynchronous(boolean async) { if (async) { flags |= FLAG_ASYNCHRONOUS; } else { flags &= ~FLAG_ASYNCHRONOUS; } }设置消息是否为异步
/*package*/ boolean isInUse() { return ((flags & FLAG_IN_USE) == FLAG_IN_USE); }是否正在使用
/*package*/ void markInUse() { flags |= FLAG_IN_USE; }设置为正在使用中
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); }打包
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]; } };实现Parcelable接口,定义CREATOR
0 0
- (M)Android消息处理机制分析之Message类解析
- (M)Android消息处理机制分析之Looper类解析
- (M)Android消息处理机制分析之Handler类解析
- Android:消息处理机制(Handler,Message,Looper)分析
- Android源码解析之消息机制系列(一)Message
- android Message 消息处理机制
- 【Android消息处理机制】android的消息处理机制(图+源码分析)——Looper,Handler,Message
- (消息处理机制)Android的消息处理机制(图+源码分析)——Looper,Handler,Message
- [Android实例] android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android 消息机制之Message
- android的消息处理惩罚机制(图+源码解析)——Looper,Handler,Message
- Android异步消息处理机制之Handler、Looper、Message
- Android 异步消息处理机制之Handler、Message、Looper
- (转)android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- TabLayout横屏TabLayout.MODE_FIXED失效
- 在.NET Core控制台应用程序中使用强类型配置
- nodejs 爬虫
- mysql常用查询语句笔记
- 5-14 Insertion or Heap Sort (25分)
- (M)Android消息处理机制分析之Message类解析
- 大型网站架构之分布式消息队列
- Laravel 定时任务
- 编译系统源码*** Can not find ProjectConfig.mk , MTK_PROJECT_CONFIGS = 。 停止。
- 解决"Notepad++中写入python代码 运行后只是一闪而过"的问题
- poj 3278 Catch That Cow 【bfs】
- 268. Missing Number#1(Done)
- android框架之基础 原型设计模式
- DOM扩展