前言
HandlerThread是线程类,HandlerThread继承了Thread,每当我们调用start()方法,run()方法就会在工作线程中执行了,也表示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;
}
HandlerThread重写了父类Thread的run()方法,当调用start()方法时,此run()方法会在工作线程中运行
1、获取线程id,并赋值给HandlerThread对象持有的int实例变量中
因为run()方法是运行在独立的线程栈中,通过调用Process的静态方法myTid()即可获得当前线程的id,然后赋值给HandlerThread对象持有的实例变量mTid存储
2、为当前工作线程创建一个Looper对象,用于消息循环
接下来调用Looper的静态放啊prepare(),静态方法prepare()会在当前Thread对象持有的ThreadLocalMap对象中添加一个元素,此元素需要传入Key对象和Value对象,Looper类持有的一个ThreadLocal对象作为Key、当前线程中创建的Looper对象则是作为Value对象
3、持有当前HandlerThread对象锁后,获取当前线程的Looper对象,通知所有等待在代码块入口处线程继续运行
当前工作线程持有HandlerThread的对象锁后才可继续执行这些,HandlerThread对象表示一个线程,但同时它也是一个对象,所以它也有对应的锁,这里要求当前线程持有对象锁的目的是为了保护共享变量mLooper,那么为什么要保护共享变量mLooper呢?先留个疑问。在临界的代码块中,先通过Looper.myLooper()方法获得当前线程缓存的Looper对象,并赋值给当前HandlerThread对象持有的mLooper变量进行保存,接着调用一个Object的native方法notifyAll(),它会通知所有在该Thread对象中处于WAITING、TIMED_WAITING状态的Thread对象苏醒继续执行
4、为当前工作线程设置优先级
使用Process类的静态方法setThreadPrioity()进行设置,设置的是HandlerThread对象持有的mPriority值
5、调用一个onLooperPrepared()方法,表示Thread中的Looper已经准备好了
作者为我们预留了一个onLooperPrepared()方法,它是proteced修饰,是专门用于我们重写的,我们可以在该方法中写一些线程中的Looper已经创建好的业务逻辑
6、工作线程将在Looper的静态方法loop()中一直循环执行
调用Looper的静态方法loop(),loop()方法内部会是“死”循环执行的,此时的HandlerThread对象已经正式开启消息循环机制(Handler机制),该线程将会不断从MessageQueue获取Message并分发出去。当MessageQueue中没有持有Message时,当前工作线程会让出CPU时间片
7、Looper的静态方法loop()退出后,为HandlerThread持有的线程id赋值为-1,表示Looper已经退出了,线程即将终结
mTid = -1,作者特意标记mTid为-1,代表消息循环已经退出
总结
1、当前工作线程启动后,在run()方法中,创建了当前HandlerThread对象中持有的Looper对象
2、调用Looper的静态方法loop(),当前工作线程会一直处于loop()方法中循环执行代码
3、作者预留待我们重写的onLooperPrepared()方法,该方法会在Looper的消息循环开始前被回调,它表示线程中的Looper已经创建好,但是消息循环还没有开始,我们可以把想在HandlerThread执行的代码写在子类重写的onLooperPrepared()方法中
4、作者在Looper的静态方法loop()结束后,即Looper退出后,使用了一条mTid = -1的语句,作为当前线程退出loop()消息循环的标志位
5、创建带有Handler机制的工作线程,HandlerThread对象是我们的首选类
6、创建完HandlerThread对象后,调用它的start()方法即可开始一个带有Handler机制的消息循环机制开始了