Android之HandlerThread源码分析(第三篇:使用方式)

前言 

    每当创建HandlerThread对象后,调用它的start()方法,一个带有Handler消息循环机制的工作线程即开始它的工作,而我们要做的就是向它内部的MessageQueue对象发送Message对象、这样我们发送过去的消息将会在HandlerThread对象所在的工作线程中得到执行。在HandlerThread中,有两个方法:

1、一个是用于获取HandlerThread对象所在工作线程的Looper对象的方法->getLooper()方法

2、另一个是用于获取HandlerThread对象持有的Handler对象,该Handler对象是与HandlerThread对象所在的线程绑定在一起的

 

getThreadHandler()方法分析

    public Handler getThreadHandler() {
        if (mHandler == null) {
            mHandler = new Handler(getLooper());
        }
        return mHandler;
    }

用于获取当前HandlerThread对象所在工作线程的Handler对象,@hide修饰,我们无法自然调用

1、Handler对象未创建,执行创建逻辑

HandlerThread对象持有的mHandler如果为null,说明Handler对象还没有创建,此时执行创建Handler的逻辑(先获取当前工作线程中的Looper对象,再创建Handler对象)

2、向调用者返回创建好的Handler对象

 

getLooper()方法分析

    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对象的方法

1、判断当前工作线程的状态

当线程状态为0时,代表线程死亡,isAlive()方法位于父类Thread类中,当线程已经死亡,getLooper()整个方法会返回null

2、获取当前HandlerThread作为对象锁后执行的代码块

调用此代码块的线程需持有当前HandlerThread对象锁,才能继续执行此代码块,为什么要在这里加锁呢?还记得在创建Looper对象的时候,也加了同一个HandlerThread对象锁?加a monitor lock的目的是为了:保证其他线程获取到HandlerThread中创建的Looper对象。

当HandlerThread中的Looper对象还没有创建时,其他线程就先执行到此getLooper()方法中,其他线程先获取到当前HandlerThread对象锁,然后进行while循环中,接着是一个Object的wait()方法的调用,会导致其他线程释放当前HandlerThread对象锁,其他线程进入WAITING状态,这样接下来当前HandlerThread对象代表的工作线程就可以去执行创建Looper对象的工作,创建完后,通过notifyAll()方法通知所有处于WAITING状态的其他线程继续运行,这样就可以保证所有的其他线程一定可以获取到一个再HandlerThread对象代表的工作线程中已经创建好的一个Looper对象。

3、向其他线程返回Looper对象

 

isAlive()方法分析

    public final boolean isAlive() {
        return nativePeer != 0;
    }

用于判断当前线程的存活状态,位于Thread类中,禁止重写,它返回了线程的存活状态,只要不是0就是代表线程存活着,当nativePeer为0时,代表Thread对象已经死亡

    private volatile long nativePeer;

该实例变量在哪被赋值的?这里留下疑问

 

总结

1、Thread对象即表示操作系统层面的实际线程,本身Thread对象也是Java中的一个对象,所以它也有对应的a monitor lock,所以当前工作线程可以持有HandlerThread对象的monitor lock也不足为奇了

2、留给我们用来创建HandlerThread对象所属的Handler对象时,只要调用它的getLooper()方法再去创建一个Handler对象即可,此时每一个Handler对象都是归属于HandlerThread对象所在的工作线程,我们利用这些Handler对象可以向HandlerThread对应的线程中发送需要执行的任务

3、HandlerThread对象对应的工作线程因为使用了Handler机制,所以当MessageQueue中没有消息时,此工作线程完全不占用CPU时间片,所以我们可以不将HandThread退出,这样在一个App进程中就有一个可以随时待命的工作线程用来执行耗时任务,随需而用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值