8

HandlerThread源码分析

 4 years ago
source link: https://blog.csdn.net/junerain25/article/details/89151660
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、 HandlerThread是什么?

  • HandlerThread本质上是一个Thread,继承Thread;
  • HandlerThread内部有自己的Looper对象,可以进行looper循环;
  • 通过获取HandlerThread的Looper对象传递给Handler对象,可以在handleMessage方法中执行异步任务
  • 与线程池不同,HandlerThread是一个串行队列,HandlerThread只有一个线程
  • 优点是不会有堵塞,减少对性能消耗,缺点是不能同时进行多任务的处理,需要等待处理

二、 HandlerThread源码分析

public class HandlerThread extends Thread {
    int mPriority;	//线程优先级
    int mTid = -1;	//线程id
    Looper mLooper;	//Looper对象
    private @Nullable Handler mHandler;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }
  • HandlerThread其实是extends Thread,内部的run方法调用了Looper.prepare()方法和Looper.loop();
@Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }
  • 但是这多了一个onLooperPrepared()方法,这里可以根据名字看出来,当Looper.prepare()创建完后,我们可以做一些初始化的东西,这当然是在子线程里,我们看下这个方法的实现。空实现,如果你要做些初始化的准备工作可以extends HandlerThread重写onLooperPrepared方法即可。
/**
     * Call back method that can be explicitly overridden if needed to execute some
     * setup before Looper loops.
*/
    protected void onLooperPrepared() {
    }
  • 退出/结束方法:quit()方法或quitSafely()方法。实际上是调用了looper.quit方法和looper.quitSafely方法
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;
    }
  • 构造Handler的时候传入了Looper,通过HandlerThread的getLooper(),源码如下。这里如果线程没有start或者一些其它原因,该线程没有处于一种存活的状态会返回null
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;
    }
  • 该函数有可能阻塞,目的是为了防止获取的looper对象为空,使用了wait方法,并且使用了局部synchronized,锁住了当前的对象,那什么时候唤醒等待呢?当然是初始化完该线程关联looper对象的地方,也就是run方法。也就是你构造完HandlerThread必须调用start方法。对于synchronized和notifyAll和wait一些线程同步处理的操作,可以参考一些资料
synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK