Handler Looper MessageQueue 关系

handler 创建时,调用Looper.myLooper()从ThreadLocal中获取当前线程looper对象,如果没有将抛出RuntimeException,so 因为当前线程创建looper ,调用Looper.prepare()方法,为当前线程创建Looper,并保存在ThreadLocal中。
调用Looper.loop()开启消息队列循环,从MessageQueue 中取出Message,并执行msg.target.dispatchMessage(msg)方法,把方法执行在Looper所在线程。

Handler引起的内存泄漏

原因:Handler内部内持有外部内的引用,导致外部activity无法释放
解决办法:

  1. 把Handler改为静态内部类,并持有activity的弱引用

2.把持有Handler引用的 Runable 跟 Message 移除掉,调用Handler.removeCallback(),removeMessages() 移除

HandlerThread

是什么: 是一个Thread内部有Looper
handlerlooper.png

使用例子

// 步骤1:创建HandlerThread实例对象
// 传入参数 = 线程名字,作用 = 标记该线程
HandlerThread mHandlerThread = new HandlerThread(“handlerThread”);
// 步骤2:启动线程
mHandlerThread.start();
// 步骤3:创建工作线程Handler & 复写handleMessage()
// 作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
// 注:消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
Handler workHandler = new Handler( handlerThread.getLooper() ) {
@Override
public boolean handleMessage(Message msg) {
…//消息处理
return true;
}
});
// 步骤4:使用工作线程Handler向工作线程的消息队列发送消息
// 在工作线程中,当消息循环时取出对应消息 & 在工作线程执行相关操作
// a. 定义要发送的消息
Message msg = Message.obtain();
msg.what = 2; //消息的标识
msg.obj = “B”; // 消息的存放
// b. 通过Handler发送消息到其绑定的消息队列
workHandler.sendMessage(msg);
// 步骤5:结束线程,即停止线程的消息循环
mHandlerThread.quit();

IntentServer

image.png
1.本质是一个特殊的service,继承自service并且本身就是一个抽象类
2.它内部通过HandlerThread和Handler实现异步操作