android_消息处理机制之Message是如何重复利用的?

  • 问题的引出

我们知道Android开发中我们是一般不会在子线程中去更新UI,而是利用Handler将当前子线程的消息post(Runnable)到主线程中去,这样就可以安全的更新UI了,看过Handler源码的同学应该知道post(Runnable
)底层就是将Runnable转化为Message然后交给Handler去处理的。这时我们发现一个问题,那就是在android中大量的UI更新是不是会创建大量的Message呢?


  • 探究android是如何去处理处理大量的Message

看看Message源码类注释,从下面的注释可以知道,它推荐我们通过Message.obtain()的方式去获取一个Message使用,还有我们看到一个关键字”recycled”,说明通过这个方法获取的Message是从回收池pool中获取的。

/**
 * 
 * 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#obtainMessagerecycleUnchecked Handler.obtainMessage()} methods, which will pull
 * them from a pool of recycled objects.</p>
 */
  • 关注怎么怎么从回收池中获取Message的

在首次调用obtain方法时,①当前pool中没有Message可用,因此会创建一个Message对象②当前pool有Message可用则直接取出表头Message。现在我发现一个问题,那就是创建了一个Message对象之后,它是什么时候添加到pool中的?

  • next:是Message的属性,是Message类型的,指向的是下一个Messae对象,因此从这点可以看出,它是一个链表的方式实现的。
  • sPoolSync:一个普通的object,纯粹是为了同步锁使用
  • sPool:表头
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 Message() {
}


  • 探索Message是怎么被存到链表中的?

首先我们要Handler的工作需要谁来配合?很简单,那就是Message,MessageQueue和Looper。下面我简单的说说每一个类的作用,详细请参考另一篇博客Handler消息处理机制

  • Message:Handler处理的消息。

  • MessageQueue:消息队列,专门负责存储消息的。
  • Looper:消息轮训器,轮训消息队列获取消息交给Handler去处理。

    知道了上面的关系之后,那么我们得找到切入点,我们知道Looper是负责轮训消息队列的,然后取出消息交给Handler去处理,那么我们就可以猜测它既然可以取消息,那么肯定需要解决handler处理的Message的,追踪源码Looper.loop()瞅瞅:

  • public static void loop() {
        final Looper me = myLooper();
        ...
        for (;;) {//阻塞
            //取出一个消息
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
            ...
            try {
                //让handler去处理这个消息
                msg.target.dispatchMessage(msg);
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            //handler处理完消息之后,回收消息
            //关键代码
            msg.recycleUnchecked();
        }
    }
    
    Message:recycleUnchecked
    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) {
            //当前pool中的Message还没有超过MAX_POOL_SIZE时
            //将将消息添加到链表中,这里就实现了pool添加Message的操作了
            if (sPoolSize < MAX_POOL_SIZE) {
                next = sPool;
                sPool = this;
                sPoolSize++;
            }
        }
    }
    • 结论

    从Message类的源码注释中也可以看出,它推荐通过Message.obtain()方法获取一个Message对象,这个可以减少内存的消耗,也是比较规范的写法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android消息处理机制是指Android系统中用于处理异步任务的一种机制。它基于事件驱动的方式,通过消息队列和线程来实现异步任务的处理。 在Android中,消息处理机制主要包括HandlerMessage和Looper三个核心组件: 1. HandlerHandler消息处理的核心,它用于发送和处理消息。每个Handler对象都关联一个特定的线程,并且在该线程中处理消息。通过Handler,我们可以发送消息消息队列,或者处理消息队列中的消息。 2. MessageMessage消息的载体,用于在不同线程之间传递信息。每个Message对象包含了一个标识符(what)、一个可选的整数参数(arg1和arg2)、一个可选的对象参数(obj)以及一个可选的Handler对象(target)。通过这些属性,我们可以传递需要处理的信息和相关的数据。 3. Looper:Looper是一个消息循环器,它用于不断地从消息队列中取出消息,并将其分发给对应的Handler进行处理。每个线程只能有一个Looper对象,它通过轮询机制实现不断地从消息队列中取出消息。 当我们需要在某个线程中处理异步任务时,可以创建一个Handler对象,并将其关联到该线程的Looper。然后,我们可以通过Handler发送消息消息队列,并在对应的Handler中处理这些消息。这样就可以实现在不同线程之间进行通信和任务处理。 总的来说,Android消息处理机制提供了一种简单而有效的方式来处理异步任务,使得我们能够更好地进行多线程编程和实现UI更新等操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值