HandlerThread
我们对于HandlerThread的分析从下面三个问题来看
1.HandlerThread是什么?
2.HandlerThread怎么用?
3.HandlerThread的源码?
1.HandlerThread是什么?
HandlerThread本质就是一个普通的Thread,里面建立了Looper
我们一般使用Handler最多的是在主线程(UI线程)中来做UI改变的工作,这个时候关于Handler的初始化操作我们不必关心,因为UI线程自动帮我们做好了,但是如果新建一个Thread在这个新的线程中去使用Handler就要初始化。HandlerThread就是一个Thread,Handler的初始化工作帮我们做好了,HandlerThread是如何做的在后面有讲解
自定义线程中使用Handler的基本操作,Handler详细的请阅读http://blog.youkuaiyun.com/chenqianleo/article/details/76977720
class ThreadWithHandler extends Thread{
Handler mHandler = null;
@Override
public void run() {
super.run();
Looper.prepare();
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//自定义处理操作
}
};
Looper.loop();
}
}
2.HandlerThread怎么用?
//HandlerThread就是一个Thread
HandlerThread handlerThread = new HandlerThread("test_01"){
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
Log.e(TAG, "onLooperPrepared: " );
}
};
//Thread开始运行
handlerThread.start();
//得到上面HandlerThread线程中初始化完成后的Looper
handler = new Handler(handlerThread.getLooper()){
//以后handler发出的操作就会在HandlerThread线程执行
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e(TAG, "handleMessage: " + Thread.currentThread().getId() );
}
};
3.HandlerThread的源码?
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
//下面2个初始化方法
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
//设置了优先级,具体的不管
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
//前面说了HandlerThread是一个Thread,run()方法很重要
//可以发现和我们自定义线程中使用Handler基本相似
@Override
public void run() {
mTid = Process.myTid(); //linux线程的Id
Looper.prepare(); //Looper初始化操作
synchronized (this) {
mLooper = Looper.myLooper(); //得到当前的线程的Looper存储起来
notifyAll(); //这个同步操作和下面的getLooper()方法进行同步操作
}
Process.setThreadPriority(mPriority);
onLooperPrepared(); //这个方法时空实现,我们可以重写它做些操作
Looper.loop(); //Looper循环起来
mTid = -1;
}
//得到当前的Looper
public Looper getLooper() {
//判断当前线程是否存活
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
//在我们调用了getLooper()时可能HandlerThread的run()方法还没有执行完毕,此时mLooper还是null,所以需要等待run()方法执行完成后唤醒getLooper()方法,简单说就是同步操作,和Handler没什么关系
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
}
HandlerThread的特点
HandlerThread将loop转到子线程中处理,将分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。
开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。HandlerThread本质是一个线程,在线程内部,代码是串行处理的。
但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。
HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。
对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。