什么是Android Handler机制?
UI更新机制和消息处理机制。
角色和角色的生成
四个主要角色
- Message:消息,包含Handler。
- MessageQueue:消息队列。
- Handler:包含MessageQueue,发送消息,处理消息。
- Looper:包含MessageQueue,遍历MessageQueue,找到待处理的消息来处理。
角色的生成
Lopper:Looper通过prepare()方法生成,生成的时候创建MessageQueue,并且将Looper对象放到ThreadLocal(保存Thread相关数据的类)中,再次调用prepare()方法的时候会抛出运行时异常。
UI线程的Looper对象在线程创建的时候自动生成,并且调用Looper.loop()死循环遍历MessageQueue
关键代码如下:
// Looper类
private static void prepare(booleanquitAllowed) {
if(sThreadLocal.get() !=null) {
throw newRuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(newLooper(quitAllowed));
}
private Looper(booleanquitAllowed) {
mQueue=newMessageQueue(quitAllowed);
mThread= Thread.currentThread();
}
Handler生成的时候会通过Looper.myLooper()去取ThreadLocal中的Looper,如果取不到会抛出运行时异常,如果取到了就将自己的MessageQueue和Looper的MessageQueue进行关联。关键代码如下:
// Handler类
public Handler(Callback callback, booleanasync) {
......
mLooper= Looper.myLooper();
if(mLooper==null) {
throw newRuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue=mLooper.mQueue;
mCallback= callback;
mAsynchronous= async;
}
Handler消息发送和处理过程
消息发送
- 将Message加入Handler的MessageQueue
- 将Message的Handler和发送消息的Handler关联(也就是Message对象持有发送它自己的Handler对象)
关键代码如下:
// Handler类
public final boolean sendMessageAtFrontOfQueue(Message msg) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, 0);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
消息处理
前面提到,UI线程启动的时候就生成了该线程Looper对象,并且调用loop()方法死循环遍历MessageQueue,所以消息处理就是当遍历到某个Message的时候就调用Message关联的Handler的handleMessage()来处理它。
Tip:
若Handler引用了Activity,而Handler发送的消息在MessageQueue中一直未被处理,会导致Activity无法被回收。
网友评论