關於message的內存優化

在Android中,在非主線程中更新UI控件是不安全的,app在運行時會直接Crash,因此當咱們須要在非主線程中更新UI控件,使用Handler和Message來實現java

而常見的實現是主線程在處理消息android

 

子線程須要更新ui,只須要發送消息安全

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

這裏獲得message的方式就有幾種app

一、直接newui

二、經過Message.obtainthis

三、經過Handler.obtainMessagespa

幾這種方式均可以用,通常狀況也沒什麼問題,可是最好仍是使用2或者3的方式,由於這兩種方式獲取Message對象就能避免建立對象,從而減小內存的開銷了。線程

 

方式一、直接new對象,沒什麼特別code

在頻繁執行的時候,可能就會形成內存的消耗增大,在某些機器上,可能內存恰好達到臨界值,這個時候再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對象就能避免建立對象,從而減小內存的開銷了。

相關文章
相關標籤/搜索