美文网首页
简说 Message.obtain()

简说 Message.obtain()

作者: 画十 | 来源:发表于2018-05-08 12:05 被阅读33次

Handler的一般做法

public class MainActivity extends Activity {

    //Demo展示,并未考虑内存泄漏等
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new Thread(new Runnable() {
            @Override
            public void run() {
                // Message message = new Message();
                Message message = Message.obtain();//更加推荐这种用法
                message.arg1 = 10086;
                handler.sendMessage(message);
            }
        }).start();
    }
}

解析

解析直接注释在下文源码中,

```
public final class Message implements Parcelable {

    Message next;
    private static final Object sPoolSync = new Object();
    private static Message sPool;
    private static int sPoolSize = 0;

    /**
    *1. sPool是static的
    *2. 如果sPool中不为空,则不new Message,而是从pool中去取
    */
    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();
    }

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

    //回收Message对象的时候,只是清空Message里面的内容,并且添加到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 = -1;
        when = 0;
        target = null;
        callback = null;
        data = null;

        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {
                //把当前Message添加到sPool首位
                next = sPool;
                sPool = this;
                sPoolSize++;
            }
        }
    }
}

```

总结:

使用Message.obtain()的好处是Message对象可以重复使用,可以免除一直new Message对象造成无谓的内存压力(不断新建销毁对象),

其他:

查看handler.sendEmptyMessage(10086);源码也可以看到,内部使用的就是obtain方法.说明这也是Google官方推荐的方式.

public class Handler {
        public final boolean sendEmptyMessage(int what){
                return sendEmptyMessageDelayed(what, 0);
        }

        public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
                Message msg = Message.obtain();//内部也是使用 obtain的方法实现的
                msg.what = what;
                return sendMessageDelayed(msg, delayMillis);
        }
}

相关文章

  • 简说 Message.obtain()

    Handler的一般做法 解析 解析直接注释在下文源码中, 总结: 使用Message.obtain()的好处是M...

  • Handler源码简析

    消息------Message 消息的复用:Message.obtain() public static M...

  • Message可以如何创建,哪种效果最好

    一共有3种方法:Message message = Message.obtain(); Message messa...

  • 安卓源码分析之Handler机制

    Handler机制 Message(消息)消息的创建:调用Message.obtain()方法,当sPool消息池...

  • Handler分析

    为什么使用Message.obtain()而不是new Message(); 查看是否有回收的消息,如果有回收消息...

  • Android Message.obtain() 之 高效原因分

    当在学习跨线程机制 Handler 时,一定会接触到 Message.obtain() 方法 当在学习Messag...

  • Message.obtain()中的单链表栈缓存

    Message.obtain()中的单链表栈缓存 Android中的Message.java用单链表实现了一个si...

  • 简说

    进入简书进行周更已经三个月了,是朋友夕子拉我进来的。之前只在QQ空间里以及微博里偶尔写一些随笔什么的,自己想怎么写...

  • 简说

    那些艰难度日的人,下一世一定会是富贵人家的。

  • 简说

    我做过淘宝做过SMT,但没想过自己会做微商[偷笑][偷笑]因为我算是个把生活和工作分开的人,在生活圈里晒工作,以前...

网友评论

      本文标题:简说 Message.obtain()

      本文链接:https://www.haomeiwen.com/subject/ivmirftx.html