继上篇文章Android之Handler源码分析/Looper,Message,Messagequeue三者关系之后,现在来总结下HandlerThread。
产生背景
平时我们在进行多任务操作的时候,会开启多个线程,但是多次创建和销毁线程是很消耗系统资源的;
通常我们是在子线程里用Handler发消息将过程或者结果反馈给主线程;那如果是主线程要主动发消息去与子线程通信呢
HandlerThread是什么
HandlerThread本质上也是一个线程,因为继承了Thread类;不过与传统Thread不同的是它内部维护了一个Looper对象,这样HandlerThread相当于存在一个MessageQueue,用来存放消息,可以创建Handler发送和处理消息;然后Looper不断轮询,没有消息就阻塞,有消息就取出消息让Handler进行处理,那开发者始终就只用维护一个线程去执行耗时操作
HandlerThread特点
- HandlerThread本质上是一个线程类,继承Thread
- HandlerThread内部维护Looper对象,可以进行消息循环
- 通过获取HandlerThread的Looper对象,将其传递给Handler对象,这样在主线程可以通过这个Handler对象发送消息,然后在handleMessage方法中执行耗时操作
- HandlerThread执行任务不会阻塞,并且只有一个线程在允许,减少了对性能的消耗
- HandlerThread是串行执行任务的,不能同时处理多任务
HandlerThread源码
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
//自己维护Looper对象
Looper mLooper;
/**
* @param name 线程名
*/
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
/**
* Constructs a HandlerThread.
* @param name 线程名
* @param priority 线程优先级
*/
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
/**
* 如果需要在Looper循环之前做设置,可以重写这个方法操作
*/
protected void onLooperPrepared() {
}
@Override
public void run() {
mTid = Process.myTid();
//初始化looper
Looper.prepare();
synchronized (this) {
//获取looper
mLooper = Looper.myLooper();
//这里主要是唤醒下面getLooper()方法中等待的线程
notifyAll();
}
//设定线程优先级,减少内存泄漏的情况
Process.setThreadPriority(mPriority);
onLooperPrepared();
//开启轮询
Looper.loop();
mTid = -1;
}
/**
* 获取Looper对象,通常是创建Handler时候使用
*/
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// 如果线程已经启动,就等待直到mLooper被创建
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
/**
* 退出消息循环
*/
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
/**
* 效率没有上面方法高,但是更安全
*/
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public int getThreadId() {
return mTid;
}
}
HandlerThread使用
private final int MAIN_THREAD_WORK = 0X01;
private final int THREAD_MAIN_WORK = 0X02;
private HandlerThread thread = new HandlerThread("handler-Thread");
private ThreadHandler threadHandler;
class ThreadHandler extends Handler{
public ThreadHandler(Looper looper){
super(looper);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//收到主线程消息,执行耗时操作
while (true) {
Log.d(TAG,"threadHandler");
//模拟耗时操作执行完,发消息给主线程
mainHandler.sendEmptyMessage(THREAD_MAIN_WORK);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Handler mainHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//收到子线程消息,更新UI
Log.d(TAG,"mainHandler");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//先开启线程
thread.start();
//再实例化子线程的Handler
threadHandler = new ThreadHandler(thread.getLooper());
//通知子线程开始做耗时操作
threadHandler.sendEmptyMessage(MAIN_THREAD_WORK);
}