这是我参与「第四届青训营 」笔记创作活动的第2天
1. Handler是什么?
我们可以把Handler放入一个线程中,去处理与线程关联的Message以及CallBack()。将Messge放入消息队列中,通过Looper去提取并处理消息。
2. 介绍一下使用方法。
这段源码是在Looper.java注释中找到的。官方已经给了我们一个使用案例。
接下来我会从run方法中依次去讲解里面的代码到底干了什么。
3.Looper.preare()
提取自Looper.java。
可以看出来prepare会从ThreadLocal中去拿Looper,如果拿不到的话会去创建一个Looper。如果已经有了一个Looper那么就会抛出异常,因为从抛出异常的信息中就可以看出来一个线程中只能有一个Looper。
4.new Handler()
提取自Handler.java。
通过构造函数去将我们创建的Handler与线程以及Looper绑定(因为一个Looper对应一个线程),同时可以看到还获得了Looper的消息队列的引用。
5. handleMessage(Message msg)
让Handler去处理对应的msg信息。
6. sendMessage
sendMessage
sendMessageDelayed
sendMessageAtTime
enqueMessgae
通过不断去找sendMessage的底层,发现最终调用的是Handler所关联的Looper中的消息队列的入队方法enqueMessgae。
7.queue.enqueMessgae
入队细节
8.Looper.loop()
for (;;) {
//细节省略
msg.target.dispatchMessage(msg);
//细节省略
}
可以看出来loop()函数是不断循环的去调用msg.target的dispatchMessage函数。
9.msg.target
那么msg.target是什么呢
可以看出来target中绑定的是handler,那么何时绑定的呢?去看6中的消息队列的入队函数代码。
10.官方推荐的俩种创建Message方法。
方法1:
提取自Messgae.java
方法2:
提取自Handler.java
方法2其实底层调用的还是方法1,那么为什么要用这种方式去创建呢,其实从源码中可以看出来,obtain方法中是在从一个对象池中去提取一个Message,优化资源的利用率。
11.dispatchMessage
接下来再看看我们在8中loop()方法中还没有讲解的一个方法。
提取自Handler.java
可以看出来,dipatchMessage会先去处理回调。如果回调是true,那么就不去执行handleMessage。如果回调是false,那么还会去执行handleMessage。