HandlerThread本質(zhì)上是通過繼承Thread類和封裝Handler類的使用,從而使得創(chuàng)建新線程和其他線程進(jìn)行通信變得更加方便易用
1.工作原理
內(nèi)部原理 = Thread類 + Handler類機(jī)制
通過繼承Thread類 快速的創(chuàng)建一個(gè)帶有Looper對(duì)象的新工作線程
通過封裝Handler類 快速的創(chuàng)建Handler與其他線程進(jìn)行通信
HandlerThread handlerThread = new HandlerThread("handlerThread");
//啟動(dòng)線程
handlerThread.start();
//創(chuàng)建工作線程和復(fù)寫handleMessage
//關(guān)聯(lián)HandlerThread的Looper對(duì)象 實(shí)現(xiàn)消息處理操作與其他線程進(jìn)行通信
//消息處理操作的(handleMessage) 的執(zhí)行線程 = handlerThread所創(chuàng)建的工作線程中執(zhí)行
Handler workHandler = new Handler( handlerThread.getLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
//消息處理
super.handleMessage(msg);
}
};
//使用工作線程Handler向工作線程的消息隊(duì)列發(fā)送消息
Message msg = Message.obtain();
msg.what = 2;
msg.obj = "B";
//通過Handler發(fā)送消息到其綁定的消息隊(duì)列
workHandler.sendMessage(msg);
//結(jié)束線程 即停止線程的消息循環(huán)
handlerThread.quit();
當(dāng)連續(xù)執(zhí)行事件時(shí),發(fā)現(xiàn)是按照順序一個(gè)個(gè)執(zhí)行,是因?yàn)槭褂肏andlerThread時(shí)只是開了一個(gè)工作線程,多次執(zhí)行事件,只是將消息發(fā)送到消息隊(duì)列,等到派發(fā)消息給Handler再進(jìn)行對(duì)應(yīng)的操作
2.Handler內(nèi)存泄露
2.1原因
1.存在"未被處理/正處理的消息" -> Handler實(shí)例 -> 外部類的引用關(guān)系
2.當(dāng)Handler消息隊(duì)列還有未處理的消息或正在處理消息時(shí),而外部類需銷毀,就會(huì)使得外部類無法被垃圾回收器(GC)回收,從而造成內(nèi)存泄露
2.2 解決方案
a.靜態(tài)內(nèi)部類 + 弱引用
private static class FHandler extends Handler {
private WeakReference<Activity> reference;
//在構(gòu)造方法中傳入需要持有的Activity實(shí)例
public FHandler(Activity activity) {
reference = new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case 1:
break;
default:
break;
}
}
}
b.當(dāng)外部類結(jié)束生命周期時(shí),清空Handler內(nèi)消息隊(duì)列
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
// 外部類Activity生命周期結(jié)束時(shí),同時(shí)清空消息隊(duì)列 & 結(jié)束Handler生命周期
}
為了保證Handler中消息隊(duì)列中的所有消息都能被執(zhí)行,此處推薦使用解決方案1解決內(nèi)存泄露問題,即 靜態(tài)內(nèi)部類 + 弱引用的方式