一、Handler的作用
实现线程间通讯,一般用于主线程跟子线程之间的通信。
可以解决主线程不能做耗时操作,子线程不能更新UI的问题。
二、Handler的原理
Handler发送的消息Message,存储到消息队列MessageQueue,由Looper关联线程并分发消息给Handler处理,回调消息到handlerMessage()。
Handler机制中的四个对象
- Handler:负责发送消息及处理消息
- Looper:消息循环器,不断的从消息队列中取出消息,并且给发送消息给Handler
- MessageQueue:负责消息的存储,单链表维护,按照FIFO规则执行。
- Message:消息本身,负责携带数据
Handler与Looper关联
- 一个线程只能有一个Looper,ThreadLocal的作用是保证了每个线程都有各自的Looper。
- 一个线程可以创建无数个Handler,但是他们使用的消息队列都是同一个,也就是同一个Looper。处理消息的时通过msg.target就可以区分开不同的Handler。
在线程中需要处理消息,必须要经过下面三个步骤,且顺序不可更改
- Looper.prepare():为当前线程准备消息队列。调用Looper.prepare()其实就是利用ThreadLocal为当前的线程创建了一个独立的Looper,并创建了一个消息队列MessageQueue。
- Handler默认构造方法跟当前线程中的Looper产生关联。在Handler中有两个全局变量mLooper和mQueue代表当前Handler关联的Looper和消息队列,并在构造函数中进行了初始化,重要的就是调用了:Looper.myLooper()。
- Looper.loop()就是一个死循环,从MessageQueue里面取消息出来交给Handler来处理。
ThreadLocal
ThreadLocal实现了线程本地存储。所有线程共享同一个ThreadLocal对象,但不同线程仅能访问与其线程相关联的值,一个线程修改ThreadLocal对象对其他线程没有影响。
三、Handler 使用
使用步骤
1、new Handler,处理回调消息handleMessage()
2、从子线程中发出消息 handler.sendMessage(message)
sendMessage 和 post 的区别
post和sendMessage本质上是没有区别的,post本质上还是用sendMessage实现的,只是用法中有一点差别。
- sendMessage主线程处理一般是写在handleMessage中。发送消息后会等对方处理完这个消息后才会继续。
- post的用法更方便,经常会post一个Runnable,处理的代码直接写在Runnable的run方法中,其实就是将这个Runnable发送到Handler所在线程(一般是主线程)的消息队列中。将消息发送出去后就会继续。
四、HandlerThread
HandlerThread 概念
HandlerThread 是一个包含 Looper 的 Thread,可以直接使用这个 Looper 创建 Handler。
HandlerThread就是一个帮我们创建 Looper 的线程,让我们可以直接在线程中使用 Handler 来处理异步任务。
HandlerThread 使用场景
当在子线程中执行耗时的、可能有多个任务的操作。
比如说多个网络请求操作,或者多文件 I/O 等等。
使用 HandlerThread 的典型例子就是 IntentService
HandlerThread 使用
HandlerThread 本质还是个 Thread,创建后别忘了调用 start()。
在 run() 方法中创建了 Looper,调用 onLooperPrepared 后开启了循环
我们可以在子类中重写 onLooperPrepared,做一些初始化工作
在创建 HandlerThread 时可以指定优先级。
参考链接
https://segmentfault.com/a/1190000019792462?utm_source=tag-newest
https://blog.youkuaiyun.com/u011240877/article/details/72905631
https://blog.youkuaiyun.com/ly502541243/article/details/87475229