- Android中,消息队列是和线程关联在一起的,每个线程最多只有一个消息队列,消息的取出和处理在线程中完成。
- Android中与消息机制相关的类主要有Looper、Handler、Message、MessageQueue。
Looper:线程的消息循环处理器。
主要特点:
* 每个线程只能有一个Looper对象;
* Looper对象中有一个消息队列MessageQueue;
* 线程默认没有Looper,需要程序自己创建Looper对象;
* Android启动时已经为主线程创建了一个Looper对象。
Looper的创建方式:
Looper.prepare();
prepare()具体实现方式为:
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
//一个线程中只能有一个Looper,多次调用会抛出异常
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
//将生成的Looper保存在静态变量sThreadLocal中 。
//ThreadLocal<Looper>类将Thread与Looper关联到一起。
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
获取主线程Looper方法:
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
loop方法
/**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
* 循环从MessageQueue队列中取出消息,通过Handler分发出去,通过Looper.quit结束
*/
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(); //可能会阻塞
if (msg == null) {
// 如果Message为空则退出
return;
}
...
//分发Message,msg.target为Handler target;
msg.target.dispatchMessage(msg);
...
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}
Handler:Message的接收者和处理者。
主要特点:
* Handler在构造时与Looper关联在一起;
* Handler与Looper是多对一的关系,即多个Handler可以对应 一个Looper;
* 可以使用Handler将Message添加到MessageQueue中;
* Handler的回调方法handlerMessage()可以对Message进行处理。
Message:消息的载体
主要特点:
* Message实现了Parcelable接口,可以通过Binder跨进程发送。