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