Android SDK源码解析篇之HandlerThread使用及源码解析
原本准备今天整理一下IntentService的源码解析,但是发现必需先总结一个HandlerThread的知识点才可以讲它,所以我今天就讲一下HandlerThread的使用及源码解析。
HandlerThread的使用
public void startHandlerThread(){ final HandlerThread myHandlerThread = new HandlerThread("myHandlerThread"); myHandlerThread.start(); workHandler = new Handler((myHandlerThread.getLooper())){ @Override public void handleMessage(Message message){ super.handleMessage(message); switch (message.what){ case 0: Log.d(TAG, "收到来自主线程的消息.."+Thread.currentThread().getName()); break; case 1: Log.d(TAG, "收到来自子线程的消息.."+Thread.currentThread().getName()); break; } } }; workHandler.sendEmptyMessage(0); new Runnable(){ @Override public void run() { workHandler.sendEmptyMessage(1); } }.run(); }程序运行结果打印如下
02-26 20:06:34.195 30062-30101/com.txVideo.demo D/LoadingActivity: 收到来自主线程的消息..myHandlerThread02-26 20:06:34.195 30062-30101/com.txVideo.demo D/LoadingActivity: 收到来自子线程的消息..myHandlerThread这段代码中我们创立了一个HandlerThread的实例对象myHandlerThread,并在workHandler中执行相关的操作.最终可以就看出不论是在主线程还是子线程发送消息,都是在这个myHandlerThread线程中工作。
源码分析
首先我们开始看HandlerThread.java的源码
public class HandlerThread extends Thread { int mPriority; int mTid = -1; Looper mLooper; private @Nullable Handler mHandler; public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } public HandlerThread(String name, int priority) { super(name); mPriority = priority; } 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; } 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; } @NonNull public Handler getThreadHandler() { if (mHandler == null) { mHandler = new Handler(getLooper()); } return mHandler; } 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其本质是Thread的子类,也就是一个子线程,里面有三个常量
int mPriority; int mTid = -1; Looper mLooper;- mPriority表示线程的优先级
- mTid表示线程的标识符
- mLooper一个Looper实例,这是HandlerThread与Thread的最大不同点。
既然是线程,那么我们看它到底在线程里做了些什么操作
@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对象的loop方法,而后当我们开始运行这个HandlerThread实例对象时,它的Looper也就开始了循环.那如何中止它呢?
public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false; }中止时就用到了上述的quit()方法。
那么接下来我们通过用法结合HandlerThread线程的原理,来分析一下它的运行过程。那么回到我们最开始的使用来逐行分析。
final HandlerThread myHandlerThread = new HandlerThread("myHandlerThread"); myHandlerThread.start();这里我们创立了一个HandlerThread的实例对象myHandlerThread,通过调用start()方法来开启了这个线程中的Looper循环。
workHandler = new Handler((myHandlerThread.getLooper())){ @Override public void handleMessage(Message message){ super.handleMessage(message); switch (message.what){ case 0: Log.d(TAG, "收到来自主线程的消息.."+Thread.currentThread().getName()); break; case 1: Log.d(TAG, "收到来自子线程的消息.."+Thread.currentThread().getName()); break; } } };接下来我们创立了一个执行myHandlerThread的工作handler,它负责HandlerThread做实际的业务,它在创立时,通过myHandlerThread的getLooper()方法来获取Looper对象,而后利用这个Looper对象来创立了这个Handler,从上篇Handler的源码分析中我们可以得知,每一个Looper维护了自己的一个消息队列,因而当我们给这个Handler发送消息时,其实也就是给myHandlerThread线程里的Looper对象发送消息,因而我们只要要在执行业务时调用
workHandler.sendEmptyMessage(0); //主线程发送消息 new Runnable(){ @Override public void run() { workHandler.sendEmptyMessage(1); } }.run(); // 子线程里发送消息我们可以通过打印结果看出其都是运行在myHandlerThread的线程中的,当我们使用完毕时,还需要关闭myHandlerThread中的Looper循环,也就是调用如下代码
myHandlerThread.quit()HandlerThread的使用还是很简单的,那么接下来我们总结一下它的工作原理:
- 新创立一个HandlerThread实例对象,并调用start()方法,它会开启线程中的Looper循环,不停地遍历所收到的消息
- 新建一个Handler,它拥有和这个HandlerThread一样的Looper对象,共同接收和遍历同一个消息队列。
- 发送消息给Handler,同时触发HandlerThread中的Looper的消息获取,而后在HandlerThread的线程中就开始执行相对应的解决消息的代码.
总结一下它的特点
- 它是Thread的子类,其本质就是一个单一的子线程
- 由于它和Handler的工作原理相似,所以它的任务执行是串行的不是并行的。
- 使用时结合Handler使用,使用完毕后需手动关闭线程中的Looper循环。
通过全篇的分析,其实HandlerThread就是为了分担主线程中的压力,去做少量其余的操作。
今天的HandlerThread原理就总结到这里啦,觉得对您有帮助记得点个赞~
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Android SDK源码解析篇之HandlerThread使用及源码解析