Message深入解析

来源:互联网 发布:nginx 参数 编辑:程序博客网 时间:2024/06/05 06:15

  Message是比较没存在感的类,用法比较简单,它是一个final类,也就是说此类无法继承。先从简单的看起。全局变量(public类):

public int what;//消息标示,public int arg1; //简单int类型数据public int arg2;//简单int类型数据public Object obj;//简单Object类型数据public Messenger replyTo;//跨进程信使public int sendingUid = -1;//Messenger消息标示

全局变量(package类):

/*package*/ static final int FLAG_IN_USE = 1 << 0;//正在使用中/*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1;//消息同步标识/*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;//任务线程/*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;//循环检查

  Message的构造方法主要有两类,一类是Google推荐的,另一类是我们普通不推荐的。
推荐构造方法:

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();}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;}public static Message obtain(Handler h) {    Message m = obtain();    m.target = h;    return m;}public static Message obtain(Handler h, Runnable callback) {    Message m = obtain();    m.target = h;    m.callback = callback;    return m;}public static Message obtain(Handler h, int what) {    Message m = obtain();    m.target = h;    m.what = what;    return m;}public static Message obtain(Handler h, int what, Object obj) {    Message m = obtain();    m.target = h;    m.what = what;    m.obj = obj;    return m;}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;}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;}

 第一个的obtain()方法是默认主要方法,后面都是对应的各种构造方法,而且Handler类里面obtainMessae方法都是直接调用Message对应的构造方法!
来看主要的构造方法obtain(),先直接加锁,然后判断消息池里面的的Message是否为空,不为空的话获取这个消息对象,然后将消息池获取下一个链表消息,并置当前的消息链表,清除使用标识,减少消息池size数量,然后返回消息,也就是Message的复用。如果为空的话,则直接调用第二种方法构造并返回。
public Message() {
}
也就是普通的构造方法。这也是为什么我们常常看见代码里面使用obtain方法获取Message对象实例而不是直接new的原因。
构造方法讲完了基本就是变量赋值,然后添加到消息队列中!其他的方法主要是一些全局变量的赋值或获取方法,没啥可说的。直接来看看消息的回收,也就是消息池的初始化:

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++;        }    }}

消息池的初始化是检查回收的时候将当前消息对象赋值给消息池的,且赋值前已经清除了所有变量,并初始化了消息并且消息链表的消息指向未赋值前的消息池,形成链表结构!
再来看看调用的方法:

public void recycle() {    if (isInUse()) {        if (gCheckRecycle) {            throw new IllegalStateException("This message cannot be recycled because it "                    + "is still in use.");        }        return;    }    recycleUnchecked();}

消息的回收,回收前直接做了判断,所以不存在Message没有使用就直接回收的情况。而且这个是public方法,也就是提供给外部调用的,而和Message直接相关的除了Handler也就是MessageQueue了,这里Handler是目标载体,而且回收的时候都释放了,不合理。也就只有MessageQueue了,去MessageQueue查找会发现在enqueueMessage方法中有调用,而且还是限定的私有方法(虽然没写方法修饰符,但MessageQueue也是final类,无法继承)。
Message类基本就是这些吧,也没啥可讲的了,下节我们来深入的了解MessageQueue!

原创粉丝点击