在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對象就能避免建立對象,從而減小內存的開銷了。