处理过程:
从handler中获取一个消息对象,把数据封装到消息对象中,通过handler的send…方法把消息push到MessageQueue队列中。
Looper对象会轮询MessageQueue队列,把消息对象取出。
通过dispatchMessage分发给Handler,再回调用Handler实现的handleMessage方法处理消息。
流程图:
Handler的实现中适及以下对象:
1、Handler本身:负责消息的发送和处理
2、Message:消息对象
3、MessageQueue:消息队列(用于存放消息对象的数据结构)
4、Looper:消息队列的处理者(用于轮询消息队列的消息对象,取出后回调handler的dispatchMessage进行消息的分发,dispatchMessage方法会回调handleMessage方法把消息传入,由Handler的实现类来处理)
Message对象的内部实现是链表,最大长度是50,用于缓存消息对象,达到重复利用消息对象的目的,以减少消息对象的创建,所以通常我们要使用obtainMessage方法来获取消息对象
安全:Handler的消息处理机制是线程安全的
关系:创建Handler时会创建Looper,Looper对象的创建又创建了MessageQueue
如何在子线程创建handler
说明:为何不能直接在子线程中创建handler
解释:在应用App启动的时候,会在执行程序的入口创建一个Looper对象:Looper.prepareMainLooper(),然后Looper.loop();完成Looper对象的创建。实际上Looper.prepareMainLooper()方法还是调用了Looper的prepare()方法完成Looper对象的创建。因此在主线程中通过关键字new创建的Handler对象之前,Looper对象已经存在并始终存在。
1、第一种
在handler前加 Looper.prepare();后加Looper.loop();
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();//Looper初始化
//Handler初始化 需要注意, Handler初始化传入Looper对象是子线程中缓存的Looper对象
mHandler = new Handler(Looper.myLooper());
Looper.loop();//死循环
//注意: Looper.loop()之后的位置代码在Looper退出之前不会执行,(并非永远不执行)
}
}).start();
2、第二种
在handler构造器中添加 handlerThread.getLooper()
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val handlerThread = com.example.handlerdemo.HandlerThread()
handlerThread.start()
val handler1 = object : Handler(handlerThread.getLooper()) {
override fun handleMessage(msg: Message?) {
super.handleMessage(msg)
Log.d("aaa", "thread:${Thread.currentThread().name},handle message")
}
}
handler1.sendMessage(Message.obtain())
}
}