Android之HandlerThread源码分析(第二篇:运行线程)

前言 

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机制的消息循环机制开始了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值