HandlerThread
2018-03-22 本文已影响17人
王小贱_ww
一.HandlerThread产生的背景
开始Thread子线程进行耗时操作,多次创建和销毁线程是很消耗资源的,但我们可以用Looper进行消息轮询机制。谷歌为我们封装好了HandlerThread(Handler+Thread+Looper)。
二.HandlerThread的特点
- HandlerThread本质上是一个线程类,他继承了Thread;
- HandlerThread内部有自己的Looper,可以进行循环
- 通过获取HandlerThread的looper对象传递给Handler对象,可以在handleMessage方法中执行异步任务。
- 优点是不会堵塞,减少了对性能的消耗,缺点是不能同时进行多任务的处理,处理效率低。
- 与线程池并发不同,HandlerThread是一个串行队列,HandlerThread背后只要一个线程。
public class HandlerThreadAcitivity extends AppCompatActivity {
private HandlerThread handlerThread;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_thread_acitivity);
handlerThread = new HandlerThread("thread");
handlerThread.start();
Log.e("tag", "main =" + Thread.currentThread().getId());
handler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e("tag", "handler =" + Thread.currentThread().getId());
switch (msg.what) {
case 1:
Log.e("tag", "收到的消息1" + "1111");
break;
case 2:
Log.e("tag", "收到的消息2" + "2222");
break;
}
}
};
// handler.sendEmptyMessage(1);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("tag", "Thread =" + Thread.currentThread().getId());
handler.sendEmptyMessage(2);
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
Log.e("tag", "Thread =" + Thread.currentThread().getId());
handler.sendEmptyMessage(2);
}
}).start();
}
}
三.HandlerThread 的源码
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
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;
}
run方法里面当mLooper创建完成后有个notifyAll(),getLooper()中有个wait(),这是为什么呢
因为mLooper在一个线程里面执行,handler的初始化是在UI线程里初始化的,也就是说要等到Looper初始化mLooper创建完成后,才能返回getLooper(),wait(),notify()就是为了解决这两个线程的同步问题。