Handler
Handler 的功能

Handler 最常用的功能就是更新 UI。因?yàn)?Android 只能在主線程中更新 UI,但是更新 UI 之前往往要先更新數(shù)據(jù),這就需要一些 I/O 操作,比如請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù),或者讀寫文件。但是這些 I/O 操作大部分都比較耗時(shí)。而 Android 中的耗時(shí)操作又需要在子線程中執(zhí)行。所以當(dāng)耗時(shí)操作完成后我們需要將更新 UI 的操作切換到主線程,或者說將更新的數(shù)據(jù)發(fā)送到主線程。此時(shí)就用到了 Handler。從上面的描述中我們可以看到 Handler 的作用是將數(shù)據(jù)從子線程發(fā)送到主線程里去操作。那么同樣的我們也可以將數(shù)據(jù)從主線程發(fā)送到子線程。此時(shí),我可以得出結(jié)論,Handler 的功能是:實(shí)現(xiàn)線程間的數(shù)據(jù)傳遞。
Handler 用法
因?yàn)?Handler 工作時(shí)需要 Looper,所以我們要為當(dāng)前線程創(chuàng)建一個(gè) Looper。如下面代碼:
Java
newThread("Thread2"){
@Overridepublicvoidrun(){
Looper.prepare();
Handlerhandler=newHandler();
Looper.loop();
}
}.start();
但是 Android 的主線程會(huì)為我們默認(rèn)初始化 Looper,所以如果在主線程中使用 Handler 就無需手動(dòng)創(chuàng)建 Looper。通常情況下,我們使用 Handler 的默認(rèn)工造函數(shù)創(chuàng)建 Handler 對(duì)象,并重寫其 handleMessage 方法。代碼如下:
Java
privateHandlerhandler=newHandler(){
@OverridepublicvoidhandleMessage(Messagemsg){
//處理Message ,比如更新 UI
}
};
然后,在耗時(shí)操作完成后,發(fā)送攜帶數(shù)據(jù)的 Message,代碼如下:
Java
newThread("Thread3"){
@Overridepublicvoidrun(){
//耗時(shí)操作,比如請(qǐng)求網(wǎng)絡(luò)
Messagemsg=Message.obtain();
handler.sendMessage(msg);
}
}.start();
其次,Handler 還可以通過 post 方法將一個(gè) Runnable 對(duì)象投遞到 Handler 中去處理。代碼如下:
Java
handler.post(newRunnable(){
@Overridepublicvoidrun(){
}
});
在上述代碼中,我們使用匿名內(nèi)部類的方式來使用 Handler,但是這種方式往往會(huì)導(dǎo)致內(nèi)存泄露。因?yàn)槟涿麅?nèi)部類默認(rèn)持有外部類的引用,如果我們?cè)?Activity 中通過上述代碼使用 Handler,那么上述 Handler 對(duì)象將持有 Activity 的引用。而執(zhí)行耗時(shí)操作的子線程持有 Handler 的引用。如果我們?cè)诤臅r(shí)操作完成之前退出 Activity,而耗時(shí)操作還沒有完成,那么子線程將繼續(xù)在后臺(tái)執(zhí)行,將導(dǎo)致 Activity 不能被正常的銷毀回收,所以將導(dǎo)致內(nèi)存泄露。