Handler知识点总结

  • Handler和Looper之间的关系,他们怎样通信的,怎么实现事件的分发

--handler通过sendMessage()发送消息到MessageQueue中,然后looper的loop()方法不断从MessageQueue中去获取消息,然后回调msg.target.dispatchMessage方法,也就是最终消息由Looper交给Handler处理。

  • 如何再一个非UI线程中启动一个Looper?

为了保证Handler关联的线程有Looper对象,可分一下两种情况:

  1. 在主UI线程中,系统已经初始化了一个Looper对象,因此程序直接创建Handler即可,然后就可以通过Handler来发送消息、处理消息了。(即之前写的博客:Handler详解(一)—关联到UI线程,非UI线程向UI线程中发送消息)
  2. 程序员自己启动的子线程,必须自己创建一个Looper对象,并启动它。创建Looper对象调用它的prepare()方法即可。prepare()方法保证每个线程最多只有一个Looper对象。UI线程向非UI线程发送消息。
  • looper.loop()内部实现机制

--loop()方法,不断从MessageQueue中去取消息,交给消息的target属性的dispatchMessage去处理。

  • Looper、Handler、Message三者关系

-----

1、首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。

2、Looper.loop()会让当前线程进入一个无限循环,不端从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。

3、Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue想关联。

4、Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。

5、在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法。

  • 若消息队列为空,线程则会阻塞等待
  • 对于Handler,如何获取当前线程的Looper?
--可以通过ThreadLocal获取当前线程的Looper


猜你喜欢

转载自blog.csdn.net/Ghost_tal/article/details/80199293