异步消息处理线程概念:
线程启动后会进入一个无限循环体(Loop)之中,每一次循环,均会从消息队列(MessageQueue)中取出一个消息,并回调对应的处理函数,执行完继续从消息队列中读取,重复执行。直到MessageQueue中无消息时,被阻塞,直到消息队列中有新的消息时,继续读取消息并处理。
消息处理部分源码:
for(;;){
//从消息队列中读取下一条消息,如果消息队列为空,则next()方法将会被阻塞;
Message msg = queue.next();
if(msg != null ){
// msg.target 对应 Handler 的实例
if(msg.target == null){
// 如果Handler为null,即无法返回具体HanlderMessage方法
return ;
// 此处部分源码省略……
}
msg.recycle();
}
}
Android的消息处理核心类:
Looper,Handler,Message,MessageQueue。
一段简单Handler用法示例,并对他进行深入分析:
Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case TestHandler.GUIUPDATEIDENTIFIER:
//省略……
break;
}
super.handleMessage(msg);
}
};
首先创建了Handler,获取当前线程的Looper对象。如果当前在主线程中创建Handler,则是MainLooper对象;
否则需要调用Looper.prepare(),为当前线程创建MessageQueue对象;
Looper.class
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对象中会创建MessageQueue对象,并且每个Looper对象与MessageQueue对象为一一对应关系;
执行Looper.loop(),使当前异步消息处理线程进入无限循环状态;
Looper.class
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// 省略……
msg.target.dispatchMessage(msg);//消费掉消息后,将结果回调至指定的Handler对象;
// 省略……
msg.recycle();
}
}
Handler的构造函数
Handler.class
public Handler(Callback callback, boolean async) {
// 省略……
mLooper = Looper.myLooper();//
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
跟进Looper.myLooper();ThreadLocal类是模板类,提供了以线程为作用域的变量存储,基本方法(set()&get());
Looper.class
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static Looper myLooper() {
return sThreadLocal.get();
}
实现Handler的CallBack接口,当Message被消费后,将由异步消息处理线程回调该方法。
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
*
* @param msg A {@link android.os.Message Message} object
* @return True if no further handling is desired
*/
public interface Callback {
public boolean handleMessage(Message msg);
}