码迷,mamicode.com
首页 > 移动开发 > 详细

Android Message详解

时间:2021-02-06 11:45:48      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:erro   消息   自己的   ini   pac   cat   modify   font   content   

一、Message定义

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>
*/

定义一个包含描述和任意数据对象的消息,该对象可以发送给Handler。
此对象包含两个额外的int字段和一个额外的object对象字段,可以使你在很多情况下不需要做分配工作。
尽管Message的构造函数是public公开属性,然而获取一个消息类最好的方式是调用Message.obtain()方法或者是Handler.obtain()方法,
它将从一个可回收对象池中获取Message对象。



二、Message成员变量

1.what(int)
/**
* 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.
*/

使用者自定义的消息标志符号,以便接收方可以识别这条消息是关于什么的。
任何一个Handler有它自己的和消息标志符对应的名称空间,因此你不用担心和其他的Handlers发生冲突。

   2.arg1 arg2 (int)

/**
* arg1 and arg2 are lower-cost alternatives to using
* {@link #setData(Bundle) setData()} if you only need to store a
* few integer values.
*/

如果你只需要保存几个integer类型的值,相对于使用setData()方法保存数据,使用arg1和arg2是低成本的替代品。

   3.obj(Object)

/**
* 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.
*/
一个发送给接受者的任意object对象。
当使用Messenger跨进程发送消息时,如果obj包含Parcelable类(),那么它只能是非空的。
对于其他数据的传递,建议使用setData()方法。请注意,在FROYO Android 2.2版本发布之前并不支持Parcelable对象。

4.replyTo(Messenger)

/**
* 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.
*/
可选的Messenger用于当前message消息发送后的回复。
具体如何使用它的含义取决于发送方和接受方。

5.sendingUid(int)

/**
* Optional field indicating the uid that sent the message. This is
* only valid for messages posted by a {@link Messenger}; otherwise,
* it will be -1.
*/
可选字段,指定发送消息的uid。该字段仅对Messenger发送的消息有效,否则将会是-1。

6.FLAG_IN_USE = 1 << 0

/** If set message is in use.
* This flag is set when the message is enqueued and remains set while it
* is delivered and afterwards when it is recycled. The flag is only cleared
* when a new message is created or obtained since that is the only time that
* applications are allowed to modify the contents of the message.
*
* It is an error to attempt to enqueue or recycle a message that is already in use.
*/
如果该属性被设置那么这条消息正在被使用。
当消息在队列时,该标志会被设置,并且在消息被传递时和之后被回收时,该标志也会保持设置。
该标志只有在新消息被created或者obtained的时候清除,因为那是应用程序允许修改消息内容的唯一时间。
尝试入队和回收一个正在使用的消息是错误的。


三、获取Message对象

/** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}).
*/
public 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();
}
从全局池中返回一个新的Message实例。
让我们在很多情况下避免分配一个新的对象。

从代码中可以看出,Message是链表结构,sPool是链表的头节点。
当链表存在头节点,将头节点取出返回使用并将计数减1,与之对应的是另一个方法。

/**
* 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。
在处理队列消息时,由MessageQueue和Looper内部使用。

由代码可以看出,消息列表是先进后出的原则,由静态变量
sPoolSync提供线程锁保证message链的线程安全。


Android Message详解

标签:erro   消息   自己的   ini   pac   cat   modify   font   content   

原文地址:https://www.cnblogs.com/SimonDonne93/p/14369614.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!