Handler发送的消息通过obtain获取

版本基于:Android R

 

0. 前言

话说在工作中第一次接触android 的Handler 的时候,不知道怎么去关注性能。

记得当时这么写的:

Message msg = new Message()
msg.what = xxx;
msg.arg1  = xxx;
msg.arg2  = xxx;
handler.sendMessage(msg);

这样使用并不是一定不允许,但是目前任何产品对于性能的要求越来越高,任何内存、调度的优化都是推荐的、可取的。

1. Handler 中注释

frameworks/base/core/java/android/os/Handler.java

    /**
     * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
     * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
     *  If you don't want that facility, just call Message.obtain() instead.
     */
    @NonNull
    public final Message obtainMessage()
    {
        return Message.obtain(this);
    }

Android 推荐使用 obtainMessage() 获取消息,因为这是从全局的message pool 中获取,而避免了create 和allocate 的操作

当然,也可以通过Message.obtain 直接获取Message,少一次转接。

2. obtain 函数

在分析obtain 函数前,需要了解Message 类中的几个注意点:

frameworks/base/core/java/android/os/Message.java

    @UnsupportedAppUsage
    /*package*/ Message next;

    public static final Object sPoolSync = new Object();
    private static Message sPool;
    private static int sPoolSize = 0;
  • 每个Message 都会有一个next;
  • 全局有个消息池 sPool;
  • sPoolSync 用于同步;

来看下obtain 函数:

frameworks/base/core/java/android/os/Message.java

    public static Message obtain() {}

    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) {}

从第二个函数开始 obtain 都是通过第一个空参的obtain 获取Message 实例;

frameworks/base/core/java/android/os/Message.java

    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();
    }

如果global pool有Message 可用,则会取出来;如果pool 中没有Message 可用,则新建一个实例;

3. recycle

frameworks/base/core/java/android/os/Message.java

    public void recycle() {
        if (isInUse()) {
            if (gCheckRecycle) {
                throw new IllegalStateException("This message cannot be recycled because it "
                        + "is still in use.");
            }
            return;
        }
        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 = UID_NONE;
        workSourceUid = UID_NONE;
        when = 0;
        target = null;
        callback = null;
        data = null;

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

Message 在调用recycle 或者recycleUnchecked的时候,会将Message 重新加入到pool 中;

4. sendToTarget 和sendMessage

如果是通过 Message.obtain() 直接获取的msg 实例,可以直接使用 sendToTarget() 发送消息。

    public void sendToTarget() {
        target.sendMessage(this);
    }

当然也可以使用 Handler.obtainMessage() 后,再通过 sendMessage() 发送消息。

为了达到发送消息的目的,这两个操作效果一样~~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

私房菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值