最近接触到一个HandlerThread类,看名字很高端大气,以为牛逼哄哄的不行。今天就从源码的角度来揭开它神秘的面纱,看看它到底是个什么玩意儿,做什么用。
先提一下假如我们要在主线程里面创建Handler,当然欧克,按照上一篇文章()讲的直接做就好了。那么在子线程呢?子线程没有现成的Looper对象,我们的MessageQueue怎么跑起来。先来看一下在子线程中如果想组成一个消息队列并更新UI怎么做。
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private static final int MSG_UPDATE = 0x100;
private Handler mThreadHandler;
private HandlerThread mHandlerThread;
private TextView textView;
private static Handler mHandler;
private MyHandler myHandler;
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.tv01);
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == MSG_UPDATE){
textView.setText(Html.fromHtml("数字每隔3秒更新:<fontcolor='#ff0000'>" +"<i>"+ (new Random().nextInt(100) + 100)+"</i>" + "</font>"));
myHandler.obtainMessage(MSG_UPDATE).sendToTarget();
}
}
};
new MyThread().start();
}
private class MyThread extends Thread{
@Override
public void run() {
Looper.prepare();
try {
Thread.sleep(3000);
} catch (InterruptedException e){
e.printStackTrace();
}
myHandler = new MyHandler();
myHandler.obtainMessage(MSG_UPDATE).sendToTarget();
Looper.loop();
}
}
private static class MyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
if(msg.what == MSG_UPDATE){
Log.i(TAG, "handleMessage:");
try {
Thread.sleep(2000);
} catch (InterruptedException e){
e.printStackTrace();
}
mHandler.obtainMessage(MSG_UPDATE).sendToTarget();
this.obtainMessage(MSG_UPDATE).sendToTarget();
}
}
}
}
实际上我们主要目标是实现在子线程创建Handler,并形成消息循环队列。只是为了和接下来的做对比,所以写了这个一个结构。下面来看看用HandlerThread来实现这样一个过程。
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private static final int MSG_UPDATE = 0x100;
private Handler mThreadHandler;
private HandlerThread mHandlerThread;
private TextView textView;
private static Handler mHandler;
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.tv01);
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == MSG_UPDATE){
textView.setText(Html.fromHtml("数字每隔3秒更新:<fontcolor='#ff0000'>" +"<i>"+ (new Random().nextInt(100) + 100)+"</i>" + "</font>"));
myHandler.obtainMessage(MSG_UPDATE).sendToTarget();
}
}
};
initBackThread();
mThreadHandler.obtainMessage(MSG_UPDATE).sendToTarget();
}
private void initBackThread() {
mHandlerThread = new HandlerThread("handlerthread");
mHandlerThread.start();
mThreadHandler = new Handler(mHandlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_UPDATE) {
try {
// 模拟从网络上获取数据的耗时操作
Thread.sleep(3000);
} catch (InterruptedException e){
e.printStackTrace();
}
mHandler.post(new Runnable() {
@Override
public void run() {
textView.setText(Html.fromHtml("数字每隔3秒更新:<fontcolor='#ff0000'>" +"<i>"+ (new Random().nextInt(100) + 100)+"</i>" + "</font>"));
mThreadHandler.obtainMessage(MSG_UPDATE).sendToTarget();
}
});
}
}
};
}
这样我们就完成了和上面同样的效果,我这里为了方便没有创建Handler子类。只是作为演示。
这样做方便了很多,实际上这个HandlerThread并没有做什么了不起的事情,只是帮我们拿到了子线程的Looper,从而可以在主线程中创建的Handler使用的却是子线程的消息循环。看看源码,
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has beenstarted, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e){
}
}
}
return mLooper;
}
当我们调用HandlerThread::getLooper()方法时,如果Looper对象还没有创建,则线程wait(),当我们调用HandlerThread::start()启动线程时会执行HandlerThrad;run()方法,
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
而run()方法中调用了Looper.prepare()方法创建了Looper的对象并保存到了ThradLocal中,随后调用notifyAll()方法唤醒正在wait()的线程,while()条件判断Looper对象不为null则跳出循环返回Looper对象。Handler拿到该Looper对象后会使用该Looper的loop()方法控制消息队列完成消息分发。至此,就算是完成了在子线程中定义Handler的操作。