HandlerThread源码解读
HandlerThread是为了方便用户使用多线程来接收处理消息的工具类。
HandlerThread源码实际上十分简洁,具体如下:
public class HandlerThread extends Thread {
private Looper mLooper;
public HandlerThread(String name) {
super(name);
}
@Override
public void run() {
Looper.prepare();//加载Looper对象到当前线程
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();//尝试唤醒getLooper()
}
Looper.loop();
}
@NonNull
public Looper getLooper() {
synchronized (this) {
if (mLooper == null) {
try {
wait();//等待Looper对象被创建
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
return mLooper;
}
}
以上代码中HandlerThread都是在围绕着looper对象的新建和获取。
先来看看Looper.prepare()做了什么
private static void prepare(boolean quitAllowed) {
//每个线程只允许执行一次该方法,第二次执行时线程的TLS已有数据,则会抛出异常。
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
//创建Looper对象,并保存到当前线程的TLS区域
sThreadLocal.set(new Looper(quitAllowed));
}
prepare函数中主要新建了Looper线程单例对象,可以理解为将Looper对象加载到了当前的线程中。
用户如果调用getLooper()时Looper对象没有被创建时,wait方法将线程挂起直到mLooper被创建加载后,调用notifyAll()唤醒。
HandlerThread使用方法
根据以下五步步骤
// 步骤1:创建HandlerThread实例对象
// 传入参数 = 线程名字,作用 = 标记该线程
HandlerThread mHandlerThread = new HandlerThread("handlerThread");
// 步骤2:启动线程
mHandlerThread.start();
// 步骤3:创建工作线程Handler & 复写handleMessage()
// 作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
// 注:消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
Handler workHandler = new Handler( mHandlerThread.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();
参考博客
Android消息机制1-Handler(Java层)
java 并发——理解 wait / notify / notifyAll
Android多线程:手把手教你使用HandlerThread