HandlerThread源码分析

HandlerThread

顾名思义,HandlerThread它是一个Thread,是Google为提高开发者效率封装的一个类。
与普通的Thread不同的是,它有一个成员属性 Looper,而Looper是用来干嘛的前一章节我们已经介绍过了。也就是说,我们的HandlerThread具有了Looper的功能。如果你有看过HandlerThread的源码,你会发现它非常短,一百多行代码。那,我们先来看线程最核心的run方法

@Override
public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}

没错,这就是我们在子线程里使用Handler时的典型用法
Looper.prepare(), Looper.loop()的使用,不同的是这里使用了一个锁,
synchronized我们当前的这个类实例,并且调用notifyAll()。为什么要多写这个呢?看到这里我也不晓得。
当我们对消息队列的处理影响到性能的时候,比如页面上的卡顿或者比较耗时的任务,那我们就可以考虑使用HandlerThread了,来看看他的用法:

private Handler mHandler;
private HandlerThread mHandlerThread;

public void initHandler() {
    mHandlerThread = new HandlerThread(Tag);
    mHandlerThread.start();
    mHandler = new Handler(mHandlerThread.getLooper());
}

我们知道,在主线程里使用Hander,我们不需要再调用Looper.prepare()和Looper.loop(),因为系统已经帮我们处理好了,主线程里的Handler使用的主线程的Looper。
使用HandlerThread,我们就可以在初始化Handler的时候,将HandlerThread里的Looper传递给Handler。这样,主线程里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;
}

初始化时getLooper(),我们发现,这里也有一个锁,也是锁住HandlerThread类实例。start HandlerThread时,会调用其run方法,run方法里会调用 Looper.prepare() 需要一定的时间, 所以在new Handler时,wait()方法等待Looper初始化完成,所以在run方法里才会有
notifyAll()的调用。

以上就是对HandlerThread的分析,是不是挺简单的呢?
根据以上的分析我们可以总结出:

  1. HandlerThread将Looper转移到子线程中处理,降低主线程的压力,不会阻塞主线程,界面显示会更流畅
  2. 子线程处理消息,因此可以处理一些比较耗时的单个任务。
  3. 由于使用消息队列的处理方式,故并发的多任务并不适用HandlerThread,会造成严重的阻塞

你可能感兴趣的:(HandlerThread源码分析)