Android开发-线程-HandlerThread

274 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情

上一篇我们介绍了安卓中线程开发的几种简单的实现方式,Thread对象和实现Runnable接口来实现线程的调用,这些都是最基础最简单的实现方式了,项目中一般需要临时用到线程的地方直接就可以使用,但是缺点就是用到的地方多了就不好维护,容易出现线程同步的问题,出了问题排查起来也比较麻烦,所以一般我们都会做一下简单的封装,统一在一个地方使用,这样维护方便,问题也容易定位,接下来我们介绍下在多线程开发中一些把线程应用到内部的对象,开篇提到了几个,这里以HandlerThread为例简单介绍下。

HandlerThread 的定义和使用

HandlerThread:其实根据字面意思就可以大致了解到,这个对象是跟Handler和Thread关系比较大的,所以HandlerThread就是具有Handler功能的Thread,怎么说呢,其实是Android将Thread和Handler进行了封装,HandlerThread本质上还是Thread,因为它还是继承自Thread,只是HandlerThread内部使用了Looper,可以进行looper循环,先简单看下源码:


/**
 * Handy class for starting a new thread that has a looper. The looper can then be 
 * used to create handler classes. Note that start() must still be called.
 */
public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;
    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }

    /**
     * Constructs a HandlerThread.
     * @param name
     * @param priority The priority to run the thread at. The value supplied must be from 
     * {@link android.os.Process} and not from java.lang.Thread.
     */
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }

    /**
     * Call back method that can be explicitly overridden if needed to execute some
     * setup before Looper loops.
     */
    protected void onLooperPrepared() {
    }

上面的源码可以看到,HandlerThread内部定义了一个Looper对象,那么Looper对象在哪里使用的呢,接着我们看下run方法:

@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的循环,那么结合Handler的原理就知道了Looper是个死循环,所以导致run方法也进入了一个死循环,那么总结下HandlerThread的机制就是:

HandlerThread在调用start方法回到run方法,在run方法中通过looper创建了一个消息队列,通过循环的方式是run方法也不会退出,这样的好处就是可以在HandlerThread中处理一些耗时操作了,但是在不需要使用的时候需要调用quit() 方法或者 quiteSafely() 方法。

HandlerThread使用

HandlerThread handlerThread = new HandlerThread("handlerThread");
handlerThread.start();

Handler msgHandler = new Handler(handlerThread.getLooper()) {

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        // 这里我们就可以处理我们的一些简单耗时操作了,比如说一个网络图片的下载等等
    }
};