Message深入解析

  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!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值