HandlerThread作为子线程管理常用类,他自带封装的Looper处理Message,可以说是十分实用。子线程调度任务,方便我们在子线程中做更多的花样。
介绍:
HandlerThread内部实现很简单,主要用在需要进行子线程调度任务的时候创建,但是想要完善熟悉原理,你必须熟悉Handler的内部原理实现。请看我的文章:【Android源码篇】 最详细的AsyncTask源码剖析
看完本文你会知道:
-
HandlerThread的用法
-
HandlerThread内部原理
HandlerThread用法
1.创建使用
-
创建HandlerThread,HandlerThread其实就是继承的Thread类
-
将HandlerThread的looper绑定到Handler
//创建HandlerThread mHandlerThread = new HandlerThread("handlerThread-test"); mHandlerThread.start(); //将HandlerThread的looper绑定到Handler mHandler = new Handler(mHandlerThread.getLooper(), new Handler.Callback() { @Override public boolean handleMessage(Message msg) { switch (msg.what) { case DELAY_1000: String str = (String) msg.obj; Log.d("handlerThread-test", "looper : DELAY_1000 " + str + " 处理线程:" + Thread.currentThread().getName()); break; case DELAY_2000: String str1 = (String) msg.obj; Log.d("handlerThread-test", "looper : DELAY_2000 " + str1 + " 处理线程:" + Thread.currentThread().getName()); break; case DELAY_3000: String str2 = (String) msg.obj; Log.d("handlerThread-test", "looper : DELAY_3000 " + str2 + " 处理线程:" + Thread.currentThread().getName()); break; case DELAY_4000: String str3 = (String) msg.obj; Log.d("handlerThread-test", "looper : DELAY_4000 " + str3 + " 处理线程:" + Thread.currentThread().getName()); break; } return false; } });
2.测试
-
在不同线程调度使用
//测试 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } asyncMessage(DELAY_1000, 0, "在子线程延时1s发送 调用线程:" + Thread.currentThread().getName()); } }).start(); asyncMessage(DELAY_2000, 2000, "在主线程延时2s发送 调用线程:" + Thread.currentThread().getName()); mHandler.post(new Runnable() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } asyncMessage(DELAY_3000, 0, "在post Runnable中sleep 3s 调用线程:" + Thread.currentThread().getName()); asyncMessage(DELAY_4000, 1000, "在DELAY_3000后延时1s发送 调用线程:" + Thread.currentThread().getName()); } }); private void asyncMessage(int what, int delay, String s) { Message message = mHandler.obtainMessage(); message.what = what; message.obj = s; mHandler.sendMessageDelayed(message, delay); }
-
结果:结果可以看出通过Handler对消息调度的处理,我们能在不同线程间进行通讯,并最终在HandlerThread异步处理
handlerThread-test: looper : DELAY_1000 在子线程延时1s发送 调用线程:Thread-5 处理线程:handlerThread-test handlerThread-test: looper : DELAY_2000 在主线程延时2s发送 调用线程:main 处理线程:handlerThread-test handlerThread-test: looper : DELAY_3000 在post Runnable中sleep 3s 调用线程:handlerThread-test 处理线程:handlerThread-test handlerThread-test: looper : DELAY_4000 在DELAY_3000后延时1s发送 调用线程:handlerThread-test 处理线程:handlerThread-test
3.退出
private void threadDestory() {
if (mHandlerThread != null) {
mHandlerThread.quitSafely();
mHandlerThread = null;
}
}
HandlerThread源码分析
查看HandlerThread内部源码,会发现,其实就只有一点代码,接下来一起分析吧
1. 构造函数中指定线程等级
/**
* Standard priority of application threads.
* Use with {@link #setThreadPriority(int)} and
* {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
* {@link java.lang.Thread} class.
*/
public static final int THREAD_PRIORITY_DEFAULT = 0;
...
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
2. Run方法中初始化looper
* 并调用 onLooperPrepared(looper执行前执行,用于处理一些准备工作)
* Looper.myLooper();绑定当前线程Looper轮询器
* Looper.loop(); 开始轮询消息
protected void onLooperPrepared() {
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
3. getLooper获取当前线程的轮询器
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;
}
4. 退出轮询,还记得Handler源码剖析里说的,Looper quit时会清理MessageQueue里面所有的消息
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;
}
网友评论