原本准备今天整理一下IntentService的源码解析,但是发现必需先总结一个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;
@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就是为了分担主线程中的压力,去做少量其余的操作。
今天的HandlerThread原理就总结到这里啦,觉得对您有帮助记得点个赞~