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());
    }
  1. 有没有感觉到代码简洁了许多,可读性增强了很多,那么他内部实现的原理是怎样的呢,在此之前最好先了解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类:

public
class 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();
  1. 接着我们调用了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)