定义:
用于线程间通讯,主要接受子线程发送的数据, 并用此数据配合主线程更新UI。(注意:Handler只能在主线程创建!!!)
为什么要用Handler:
UI线程不能耗时操作,超过5s会报ANR异常,所以我们需要开启子线程做耗时操作,但是线程间不能直接通讯,所以Android为我们提供了Handler用于线程间通讯。(广播也可以线程间通讯)
Handler发送消息的方法:(在子线程发送消息,主线程创建Handler)
两种消息类型:runnable和message(多线程实现方式implements Runnable或 extends Thread)
post(Runnable)、postAtTime(Runnable,long)、
postDelayed(Runnable long)、sendEmptyMessage(int)
sendMessage(Message)、sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
Handler、Looper、MessageQueue示意图:
这里注意几点:looper循环拿到MQ的消息;发送和接受消息都是通过Handler;
looper、MQ和Handler都在主线程。
注意:某些情况下会出现内存泄露
原理:非静态内部类持有外部类匿名应用可能会造成内存泄露;
解决方法:非静态内部类改为静态内部类;(原理:静态内部类不持有外部类的引用)
使用弱引用;
下面来看看源码:
首先看Handler构造方法,这创建了looper和MQ,在进入looper中你会发现三者是在同一个线程。
(sendMessage()----> enqueueMessage()方法表示插入消息)
looper的创建,这里的ThreadLocal是java方法,任意线程调用ThreadLocal其get()和set()方法都是在调用线程。
如:这里调用是UI线程,所以get和set就在UI线程。
这里可以看到prepare()中 ThreadLocal添加looper
这里是looper中的loop()方法 消息通过这个死循环来轮训消息 当没有消息时 会自动阻塞 (Linux 会开启一个管道用于管理阻塞)
通知红框内,可以看到消息分发出去是通过dispatchMessage发送的,如果进入msg中,你会发现target这个变量其实就是Handler,所以looper是通过Handler发送消息的。
onPostExecute
最后来看看Handler中的dispatchMessage方法,这里可以看到最终数据又回到handleMessage中。至此行程了一个循环