handler源码学习(2) — Message

5 篇文章 0 订阅
4 篇文章 0 订阅

这是Handler源码学习第二篇,后续还有
handler源码学习(1) — Handler
handler源码学习(2) — Message
handler源码学习(3) — Looper
handler源码学习(4) — MessageQueue

message相对来说比较简单,大部门代码都是对一些属性值的赋值和获取以及Parcelable的实现。这里我们主要看一下几个方法

    public Message() {
    }
    
    / 1
    public static Message obtain() {
        //sPoolSync 锁,因为可能多个线程同时obtain(),所以加锁
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;//将mPool赋值给m
                sPool = m.next;//sPool等于链表的m.next。也就是原来的sPool的下一个
                m.next = null;//将m.next置为null。至此spoll和m没有链表关系
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }
    
    public static Message obtain(Message orig) {···}
    
    public static Message obtain(Handler h) {···}
    
    public static Message obtain(Handler h, Runnable callback) {···}
    
    public static Message obtain(Handler h, int what) {···}
    
    public static Message obtain(Handler h, int what, Object obj) {···}
    
    public static Message obtain(Handler h, int what, int arg1, int arg2){··· }
    
    public static Message obtain(Handler h, int what,
            int arg1, int arg2, Object obj) {···}

重点看下注释1,其他都是很常规的一些方法。
说白了就是同步取sPool(注意是静态的)的第一个,并且返回。不过这里有个点需要关注,就是什么时候对sPool赋值,什么时候添加next。我们找一下sPool的赋值,很容易找到

    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 = UID_NONE;
        workSourceUid = UID_NONE;
        when = 0;
        target = null;
        callback = null;
        data = null;

        //1
        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {
                next = sPool;
                sPool = this;
                sPoolSize++;
            }
        }
    }

其实就是将当前的message的所有变量置为初始状态,同时(注释1)将其添加到sPool(是静态的)的链表头。注释1举个例子:

val 当前msg = this;
spool = 1msg
当前msg.next = 1msg
spool =当前msg(当前msg.next = 1msg)
所以此时的spool就是 当前msg,1msg

所以到这里我们基本上就明白了obtain和直接new Message()的区别。

总结

message就如它的翻译消息。他就是一个标准的消息,里面包含了我们跨线程要传递的东西。

本篇我们解决了问题:

  • obtain和直接new Message()的区别
    • 消息recycle()后,会被缓存到静态变量sPool中。spool是一个单链表。使用obtainxxx()会直接从sPool中取第一个message来复用。避免了重复创建过多消息对象。

留下疑问:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值