首页 > IT职业 > IT生活 > 深入理解Android异步消息处理机制
Android 中的异步消息处理主要分为四个部分组成,Message、Hndler、MessageQueue 和 Looper。其关系如下图所示:

1. Message 是线程之间传递的消息,它可以在内部携带少量信息,用于在不同线程之间交换数据。
2. MessageQueue 是消息队列,它主要用于存放所有由 Handler 发送过来的消息,这部分消息会一直在消息队列中,等待被处理。每个线程中只会有一个 MessageQueue 对象。
3. Handler 是处理者,它主要用于发送和处理消息。 发送消息一般使用 handler 的 sendMessage()方法,处理消息会调用 handleMessage() 方法。
4. Looper 是每个线程中 MessageQueue 的管家, 调用 loop() 方法后,就会进入到一个无限循环当中,然后每当发现 MessageQueue 中存在一条消息,就会将其取出,并传递到 handleMessage()方法当中。每个线程中也只会有一个Looper对象。
接下来我们看一下Looper的构造函数:
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mRun = true;
mThread = Thread.currentThread();
}
在 Looper 的构造函数中,创建了 MessageQueue 对象,这也保证了一个线程只有一个 MessageQueue 对象。
然后我们看看 loop() 方法:
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;
} // This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging; if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg); if (logging != null) {
logging.println("这个方法先调用 myLooper() 方法,得到 sThreadLocal 中保存的 Looper 对象,并得到 looper 对象对应的 MessageQueue 对象,然后就进入无限循环。
该循环主要包括:取出一条消息,如果没有消息则阻塞; 调用 msg.target.dispatchMessage(msg);把消息交给msg的target的dispatchMessage方法去处理。
Looper主要作用:
1、 与当前线程绑定,保证一个线程只会有一个Looper实例,同时一个Looper实例也只有一个MessageQueue。
2、 loop()方法,不断从MessageQueue中去取消息,交给消息的target属性的dispatchMessage去处理。
http://www.codeceo.com/article/android-asyn-message.html
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2157/viewspace-2806315/ ,如需转载,请注明出处,否则将追究法律责任。