HandlerThread源码解析

1、HandlerThread 是什么?

它继承至 Thread,具备线程的特性。它是一个带有 Looper 的线程,并且该Looper可以被用于创建对应的Handler。

2、HandlerThread的作用是什么?

当一个线程执行完一个耗时任务之后,如果想要再执行另外一个耗时任务那么就需要重新创建一个新的线程,而多次进行线程的开启和销毁的是需要很大的开销。在一般情况下,线程被开启之后,也就是run方法会被执行,若需要动态地在执行过程做一些其它处理,例如根据不同的条件执行不同的代码块,显然是比较麻烦的。而HandlerThread解决了这个问题,它内部维护了一个Looper不断地去轮训消息队列,当需要在子线程做其他操作时,只需要通过绑定的Handler去发送消息,然后处理即可。

3、HandlerThread的工作原理

HandlerThread 是一个内部维护一个 Looper 对象的线程。这样就省去了创建线程时需要手动的创建 Looper 的麻烦。而已它内部使用了
wait() 和 notifyAll() 保证的 Looper 的非空性控制。

3.1、HandlerThread#run()

  • 该方法是一个loop()的死循环,等待消息的到来。
  • Looper.prepare()创建Looer对象并保存到ThreadLocal中。
  • Looper.myLooper()获取通过preparen()保存的Looper对象。
  • loop()开启轮训器轮训。
public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        
        mLooper = Looper.myLooper();
        //在这里的 Looper 已经创建完毕,通知 getLooper 不需要等待啦。
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();//空的回调,交由用户做一些loop()前的准备工作。
    Looper.loop();
    mTid = -1;
}

3.2、HandlerThread#getLooper()

获取关联的Looper对象,可用于外部创建Handler的构造参数,该方法中有一个wait()方法,然后在run()中一个notifyAll()方法,他们的作用就是在getLooper时为了保证能正确的获取到当looper对象,当looper为null,就让其等待,直到run()方法创建了其Looper对象之后调用notifyAll唤醒。

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;
}

3.3、移除消息队列中的消息

//立即退出
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;
}

4、 IntentService 内部 HandlerThread 的应用


@Override
public void onCreate() {
    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    //开启线程
    thread.start();
    //getLooper 是一个阻塞方法。
    mServiceLooper = thread.getLooper();
    //Handler 绑定一个通过 HandlerThread 创建的 looper 对象。
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

    原文作者:未见哥哥
    原文地址: https://www.jianshu.com/p/25bb25f1750e
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞