android 多线程 — HandlerThread
今天我们来看一个简单的 HandlerThread,前面我们学习过了 handle ,现在再来看 HandlerThread 会发现真是简单的不得了
HandlerThread 简单的说就是 在一个 Thread 里面封装了一个 looper ,然后启动该 looper ,外接和这个 HandlerThread 的交互都是通过 handle 发送消息,因为 HandlerThread 可以返回其虐不的 looper 对象,然后我们用这个 looper 对象创建 handle 对象发送消息
HandlerThread 的用法
// 创建 HandlerThread 对象并启动 HandlerThread 所属线程,构造方法需要传线程的名字进去
HandlerThread handlerThread = new HandlerThread("AAAAAAAA");
handlerThread.start();
// 通过 HandlerThread 对象内部的 looper 构建用于通讯的 handle
Handler otherHandle = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
Log.d("AAA", Thread.currentThread().getName() + "接受消息" + System.currentTimeMillis());
}
}
};
// 执行线程间通讯任务
otherHandle.sendMessage(Message.obtain());
// 不需要了就关闭线程
handlerThread.quit();
大家要是吧前面我说 handle 的那篇搞明白,这 HandlerThread 的使用实在不是要太简单了
看看源码吧
其实猜都能猜到的,这是 HandlerThread 声明的成员变量
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
private @Nullable Handler mHandler;
{
这是核心 run 方法
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
在线程启动时把 looper 消息队列跑起来
有意思的地方来了
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
// 会阻塞
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
大家注意 getLooper() 方法是给别的线程调用的,因为 handle 的构造方法不能接受 null 的 looper 对象,要不会抛异常,所以这里在其他线程获取 HandlerThread 的 looper 对象时,若是发现此时 looper 对象是 null 的,那么就会阻塞调用 getLooper() 方法的外部线程。
直到 run 的初始化同步代码段跑完,此时 looper 初始化完成,会主动唤醒所有阻碍在 looper 对象身上的 线程,我们再来看看 HandlerThread 的run 方法
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
// 主动唤醒所有阻碍在 looper 对象身上的 线程
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
好了,HandlerThread 很简单的,这里就基本完事了。我们看 HandlerThread 源码一定要理解 HandlerThread 为啥要 wait,什么时候 notifyAll 。这个是 HandlerThread 里面最值得学习的点,学会了很有用的。