Handler大家都在用,用來線程的通信,實現(xiàn)異步間的信息傳遞
handler有個小坑 不優(yōu)化的話 會引起內(nèi)存泄漏
要從handler機制說起,Android中UI線程也就是主線程建立時,會進(jìn)行一個Looper.prepare()的方法,每個looper對應(yīng)一個線程,這是一個類似輪詢器的玩意兒,這個東西會不停地去輪詢Messagequeue消息隊列,取出處于隊列頭部的消息,發(fā)送給相應(yīng)的線程
大體的一個機制就是這樣,然后問題就出在了消息隊列這一塊,handler發(fā)送消息,不是說發(fā)送一個就完事,要不然也就用不到消息隊列了,假設(shè)這樣一個情況,消息隊列中有五個消息,都是由子線程發(fā)送給主線程的,主線程在處理了兩個消息之后被用戶關(guān)閉了,這是很有可能的一個情況,activity關(guān)閉是關(guān)閉了 但是這個時候handler還持有著activaty的引用,這就會導(dǎo)致activity的內(nèi)存回收不了,出現(xiàn)內(nèi)存泄漏
具體優(yōu)化方法如下 簡單的加一個軟引用
static class LoadDataHandler extends Handler {
private SoftReference<MainActivity> activitySRF = null;
public LoadDataHandler(MainActivity activity) {
activitySRF = new SoftReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// 因為Handler是異步的排嫌,存在退出當(dāng)前類之后才接收到handler消息的情況畸裳,
// 并且軟引用持有的對象會在堆內(nèi)存不足時存在被回收的可能,所以這里需要判空處理
if (null == activitySRF || null == activitySRF.get()) {
return;
}
switch (msg.what) {
case 0: {
activitySRF.get().mUserNameTxt.setText("123");
}
break;
default:break;
}
}
}