Android(安卓)HandlerThread的用法
在进行Android开发很多时候都会用到线程调度,使用较多的就是Handler和Thread,其实Android还为我们封装了他们的结合体HandlerThread,那么他是个什么东西呢,又是怎么工作的,我们今天就来从源码角度来分析一下HanderThread
我们知道在线程里面创建Handler需要先调用Looper.prepare()创建looper,最后调用Looper.loop()开启循环,使用示例代码如下:
new Thread(){ @Override public void run() { Looper.prepare(); handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); } }; Looper.loop(); } }.start();
一不小心忘记创建了looper可能会报错,或者忘记开启了消息队列的循环可能导致消息不能得到处理,有没有把这些都封装好的接口可供我们调用呢,这就是我们今天要讲的HandlerThread。我们先看看HandlerThread的使用方法:
HandlerThread handlerThread = new HandlerThread("test"); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); }
- 有没有感觉到代码简洁了许多,可读性增强了很多,那么他内部实现的原理是怎样的呢,在此之前最好先了解Handler+Looper+MessageQueue+Message,可以参考源码解析Handler,了解了Handler的创建和消息处理流程后我们再来看看HandlerThread的源码:
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; }
可以看到HandlerThread实际上是继承了Thread,等同于我们new Thread()而Thread又是实现了Runnable类:
publicclass Thread implements Runnable { /* Make sure registerNatives is the first thing does. */ /** * The synchronization object responsible for this thread's join/sleep/park operations. */ private final Object lock = new Object();
- 接着我们调用了handlerThread.start(),看一下这个start方法里面干了什么:
/** * Causes this thread to begin execution; the Java Virtual Machine 重点在这,调用了start(方法后系统会回调run方法) * calls the run
method of this thread. * 。。。。。。 public synchronized void start() { // Android-changed: throw if 'started' is true if (threadStatus != 0 || started) throw new IllegalThreadStateException(); group.add(this); started = false; try { nativeCreate(this, stackSize, daemon); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }
从上面的注释可以看到系统会回调run方法,而HandlerThread继承了Thread且重写了run方法,所以最终回调执行的是HandlerThread里面的run方法,看下HandlerThread里面的run方法的实现:
@Override public void run() { mTid = Process.myTid(); //创建Looper Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); //开启循环 Looper.loop(); mTid = -1; }
可以看到之前需要自己手动操作的行为只要调用一下start,内部都给你封装好了,同时还提供了获取looper的方法,用于创建Handler的时候传入,因为此handler发出消息的执行是在UI线程还是工作线程执行就是取决于我们传入的Looper对象是在UI线程创建的还是在工作线程创建的,详细说明可以参考上面链接的Handler文章的相关知识:
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; }
到此,应该可以看明白了,HandlerThread的工作原理其实和new Thread+Handler的相同,区别就是HandlerThread的使用更加友好,使用者不需要关注更多的内部实现细节,减少了使用的代价。
更多相关文章
- Android(安卓)studio 快捷键汇总
- Android切近实战(三)
- 使用ProGuard遇到“conversion to Dalvik format failed with er
- android+kotlin开发笔记(一)
- Android从源码分析一:Looper,Handler消息机制
- android XML文件解析之 SAX解析方法
- 结合Android浅谈Builder模式
- 下载最新Android代码的方法
- android-如何在子线程中更新ui