关于message的内存优化

Posted seven-sky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于message的内存优化相关的知识,希望对你有一定的参考价值。

android中,在非主线程中更新UI控件是不安全的,app在运行时会直接Crash,所以当我们需要在非主线程中更新UI控件,使用Handler和Message来实现

而常见的实现是主线程在处理消息

 

子线程需要更新ui,只需要发送消息

//Message message = new Message();
Message message = mHandler.obtainMessage();
message.what = out.what;
message.obj = out.clone();
mHandler.sendMessage(message);

这里得到message的方式就有几种

1、直接new

2、通过Message.obtain

3、通过Handler.obtainMessage

几这种方式都可以用,一般情况也没什么问题,但是最好还是使用2或者3的方式,因为这两种方式获取Message对象就能避免创建对象,从而减少内存的开销了。

 

方式1、直接new对象,没什么特别

在频繁执行的时候,可能就会造成内存的消耗增大,在某些机器上,可能内存刚好达到临界值,这个时候再new message之后,可能会出现崩溃

本人遇到过这样的问题,底层每两秒给一个消息到应用层更新ui,在大部分机器都没有问题。但是在一个android4.4的设备上,会经常出现崩溃,特别是在handle.sendMessage

频繁的时候基本必现,通过把message的获取方式从new改成obtian,问题解决。

 

方式2的源码实现:

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

}

 

方式3的源码实现:

Message msg1 = handler1.obtainMessage();

 

public final Message obtainMessage()
    {
        return Message.obtain(this);
    }

public static Message obtain(Handler h) {
        Message m = obtain();
        m.target = h;

        return m;
    }

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对象,所以建议用第二种或者第三种任何一个创建Message对象。

通过调用obtainMessage方法获取Message对象就能避免创建对象,从而减少内存的开销了。

以上是关于关于message的内存优化的主要内容,如果未能解决你的问题,请参考以下文章

代码片段

WEB性能优化-浏览器缓存&内存中的猎者&Commit message编写指南--20170702冰鉴周指南

Selenium Xpath元素无法定位 NoSuchElementException: Message: no such element: Unable to locate element(代码片段

关于博客优化2.0

SQLServer 2014 内存优化表

优化 C# 代码片段、ObservableCollection 和 AddRange