android开发:HandlerThread源码解析

日常开发我们做耗时任务时都是直接创建一个线程去执行,执行完毕后又销毁。当然这样做并没什么毛病,但是如果执行的耗时任务很多,每个任务我们都要创建线程去执行,性能肯定是不好的。那么可不可以创建一个 带消息队列的线程,线程不断的从队列中取出任务执行。当队列没有任务时线程处于等待,当我们向队列中放入任务时线程又从队列中取出执行。android向我们提供了HandlerThread,他本质上是一个线程,只不过其内部帮你实现了一个Looper的循环而已。android主线程其实就是HandlerThread,主线程创建时实现了Looper,Looper不断的从消息队列拿消息,我们通过handler发送message到主线程的消息队列,Looper拿到message后调用handler的handleMessage()。

Android开发:带你了解Android的消息机制-通俗易懂

HandlerThread源码分析:

26public class HandlerThread extends Thread {
27    int mPriority;
28    int mTid = -1;
29    Looper mLooper;
30    private @Nullable Handler mHandler;
31
32    public HandlerThread(String name) {
33        super(name);
34        mPriority = Process.THREAD_PRIORITY_DEFAULT;
35    }
36
37    /**
38     * Constructs a HandlerThread.
39     * @param name
40     * @param priority The priority to run the thread at. The value supplied must be from
41     * {@link android.os.Process} and not from java.lang.Thread.
42     */
43    public HandlerThread(String name, int priority) {
44        super(name);
45        mPriority = priority;
46    }
47

从源码可以看到HandlerThread 继承Thread,构造函数中调用父类的构造方法来创建线程。

run()方法解析:

55    @Override
56    public void run() {
57        mTid = Process.myTid();
		 //创建Looper
58        Looper.prepare();
59        synchronized (this) {
60            mLooper = Looper.myLooper();
			//唤醒线程
61            notifyAll();
62        }
		 //设置优先级
63        Process.setThreadPriority(mPriority);
64        onLooperPrepared();
		//Looper开始工作
65        Looper.loop();
66        mTid = -1;
67    }

在run()方法中创建Looper并开始启动looper工作(Looper创建的时候会创建消息队列)

getLooper()方法:

75    public Looper getLooper() {
76        if (!isAlive()) {
77            return null;
78        }
79
80        // If the thread has been started, wait until the looper has been created.
81        synchronized (this) {
82            while (isAlive() && mLooper == null) {
83                try {
84                    wait();
85                } catch (InterruptedException e) {
86                }
87            }
88        }
89        return mLooper;
90    }
91

getLooper()获取当前线程的looper对象,如果当前线程未启动直接返回,若启动了但是looper对象未创建线程先挂起。因此在上面run()方法中调用notifyAll()其实就是为了唤醒线程。(就是线程启动了但是looper对象还没创建好,那就先调用wait(),在run()中looper创建好了再唤醒)

HandlerThread的使用:

//创建线程,name是线程名
 HandlerThread handlerThread = new HandlerThread("name");
 //启动线程
        handlerThread.start();
		//创建handler,绑定Looper
        final Handler handler = new Handler(handlerThread.getLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
            //打印线程
            System.out.println(Thread.currentThread().getName());
            System.out.println(msg.arg1);

            }
        };

        new Thread() {
            @Override
            public void run() {  
                Message message = new Message();
                message.arg1 = 1;
                //在另外的子线程中发送消息
                handler.sendMessage(message);
            }
        }.start();

输出结果:
2019-12-04 15:35:41.559 26537-26618/? I/System.out: name
2019-12-04 15:35:41.560 26537-26618/? I/System.out: 1

1.创建HandlerThread,然后启动。(HandlerThread创建时会创建Looper和消息队列,并且启动Lopper开始工作)
2.getLooper()获取HandlerThread的looper对象
3.创建handler,并且和looper绑定。
4.handler发送消息
5.handler的handleMessage()处理消息

handler发送消息其实就是往HandlerThread线程的消息队列中插入一条消息,looper拿到消息后会调用handler的handleMessage(),而looper又是工作在HandlerThread线程中,所以不难理解handleMessage()为什么会在该线程中工作,使用handler更新UI的时候也是一样,handler绑定的是主线程的looper对象,发送消息后在主线程looper中调用handler的handleMessage(),因此可以在handleMessage()更新UI.
因此HandlerThread结合handler我们就可以实现线程间的通信,当存在多个任务时handler发送多个消息,然后handleMessage()不断的执行任务。而我们只需要创建HandlerThread一个线程就可以搞定,当我们activity退出的时候关闭HandlerThread就可以了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值