参考文章:
深入理解Handler机制
Android 事件机制详解
Android Handler消息机制的理解
android的消息处理机制(图+源码分析)——Looper,Handler,Message
在开发中,Handler通常用于异步消息处理,相关联的类有:
ThreadLocal、Looper、MessageQueue、Message、Handler.
Handler持有MessageQueue和Looper,而Looper持有持有MessageQueue,Message中包含Handler和Runnable成员变量。
其中
在一个线程中通过调用Looper.prepare();初始化即可使线程成为Looper线程,通过Looper.loop() 来循环处理消息队列
参考资料:解密ThreadLocal
正确理解ThreadLocal
ThreadLocal提供了线程局部变量,在线程的生命周期内起作用,使得各线程能够保持各自独立的一个对象,在Thread中将new出来的对象通过ThreadLocal.set()来设置独立于其他线程的对象,其他线程不可访问,不是用来解决线程同步问题的。
每个线程中都有一个ThreadLocalMap类对象,而ThreadLocal实例就是key,value是真正需要存储的Object,在Android’Handler机制中就是我们的Looper对象。
public final class Looper {
private static final String TAG = "Looper";
// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;
private Printer mLogging;
//....
通过Looper.prepare();来初始化Looper,并将Looper对象存储到本地线程中,而后创建Handler对象,并掉用Looper.loop()方法进行轮询。
注意:一个线程可以有多个Handler,每个线程中只有一个Looper对象。
public static void prepare()
{
prepare(true);
}
private static void prepare(boolean quitAllowed)
{
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed)); // 创建Looper对象,并设置进TLS
}
//.....
public static final void loop() {
Looper me = myLooper(); //得到当前线程Looper
MessageQueue queue = me.mQueue; //得到当前looper的MQ
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
// 开始循环
while (true) {
Message msg = queue.next(); // 取出message
if (msg != null) {
if (msg.target == null) {
// message没有target为结束信号,退出循环
return;
}
//...
// 将真正的处理工作交给message的target,即发送消息的handler
msg.target.dispatchMessage(msg);
首先,来看一下handler 的构造函数,
public Handler(Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();// 设置looper
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue; //设置MessageQueue
mCallback = callback; //设置CallBack
mAsynchronous = async;
}
Handler对象在构造时,不但会把Looper对象记录在它内部的mLooper成员变量中,还会把Looper对象的消息队列也一并记录
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
handler中的post 和send方法都会最终调用sendMessageAtTime方法,通过enqueueMessage方法将消息压入MessageQueue中
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this; // message的target必须设为该handler!
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
这个方法是有Looper.loop()方法调用。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
// 如果message设置了callback,即runnable消息,处理callback!
handleCallback(msg);
} else {
// 如果handler本身设置了callback,则执行callback
if (mCallback != null) {
/* 让activity等来实现Handler.Callback接口,避免了自己编写handler重写handleMessage方法。*/
if (mCallback.handleMessage(msg)) {
return;
}
}
// 如果message没有callback,则调用handler的钩子方法handleMessage
handleMessage(msg);
}
}
// 处理runnable消息
private final void handleCallback(Message message) {
message.callback.run(); //回调CallBack中的run方法!
}
// new Handler的时候需要实现的方法
public void handleMessage(Message msg) {
}