Handler
Handler 的功能
Handler 最常用的功能就是更新 UI来颤。因?yàn)?Android 只能在主線程中更新 UI汰扭,但是更新 UI 之前往往要先更新數(shù)據(jù),這就需要一些 I/O 操作福铅,比如請求網(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 對象掺喻,并重寫其 handleMessage 方法芭届。代碼如下:
Java
privateHandlerhandler=newHandler(){
@OverridepublicvoidhandleMessage(Messagemsg){
//處理Message 储矩,比如更新 UI
}
};
然后,在耗時(shí)操作完成后喉脖,發(fā)送攜帶數(shù)據(jù)的 Message椰苟,代碼如下:
Java
newThread("Thread3"){
@Overridepublicvoidrun(){
//耗時(shí)操作,比如請求網(wǎng)絡(luò)
Messagemsg=Message.obtain();
handler.sendMessage(msg);
}
}.start();
其次树叽,Handler 還可以通過 post 方法將一個(gè) Runnable 對象投遞到 Handler 中去處理舆蝴。代碼如下:
Java
handler.post(newRunnable(){
@Overridepublicvoidrun(){
}
});
在上述代碼中,我們使用匿名內(nèi)部類的方式來使用 Handler,但是這種方式往往會(huì)導(dǎo)致內(nèi)存泄露题诵。因?yàn)槟涿麅?nèi)部類默認(rèn)持有外部類的引用洁仗,如果我們在 Activity 中通過上述代碼使用 Handler,那么上述 Handler 對象將持有 Activity 的引用性锭。而執(zhí)行耗時(shí)操作的子線程持有 Handler 的引用赠潦。如果我們在耗時(shí)操作完成之前退出 Activity,而耗時(shí)操作還沒有完成草冈,那么子線程將繼續(xù)在后臺(tái)執(zhí)行她奥,將導(dǎo)致 Activity 不能被正常的銷毀回收,所以將導(dǎo)致內(nèi)存泄露怎棱。