![](https://img-blog.csdnimg.cn/b9e36dd408914a259ab724b190199219.png)
2012年2月加入去哪儿网,多次参与 Android 客户端的重构,插件化开发,客户端安全攻防,现负责国际酒店抓取系统架构升级维护。
Android 应用程序是通过消息来驱动的,系统为每一个应用程序维护一个消息队例,应用程序的主线程不断地从这个消息队例中获取消息(Looper),然后对这些消息进行处理(Handler),这样就实现了通过消息来驱动应用程序的执行。先了解一下涉及到的几个概念:
- Message
消息(Message)代表一个行为(what)或者一串动作(Runnable),每一个消息在加入消息队列时,都有明确的目标(Handler)。
- MessageQueue
以队列的形式存放消息对象,其内部结构是以链表的形式存储消息。对外提供插入和删除操作。
- Looper
Looper 是循环的意思,它负责从 MessageQueue 中循环的取出 Message 然后交给目标(Handler)处理。
- Handler
消息的真正处理者,具备获取消息、发送消息、处理消息、移除消息等功能。
- ThreadLocal
作用是为了线程隔离,内部实现相当于Map以当前线程为key,存入的值作为 value。
Looper 不断从 MessageQueue 中取出一个 Message,然后交给其对应的 Handler 处理。
我们平时接触到的 Looper、Message、Handler 都是用 JAVA 实现的,Android 是一个基于 Linux 的系统,底层用C、C++实现的,而且还有 NDK 的存在,Android 消息驱动的模型为了消息的及时性、高效性,在 Native 层也设计了 Java 层对应的类如 Looper、MessageQueue 等。
在 ActivityThread 的 main 函数里面调用主线程的 loop 方法开启消息循环监听,这个 loop 方法会一直运行,伴随应用的整个生命周期。
以下是 ActitivyThread 的 main 的实现:
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “ActivityThreadMain”);
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
prepareMainLooper 做的事情其实就是在线程中创建一个 Looper 对象:
/**
* Initialize the current thread as a looper, marking it as an
* application's main looper. The main looper for your application
* is created by the Android environment, so you should never need
* to call this function yourself. See also: {@link #prepare()}
*/
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
先调用 prepare 来进行主要成员变量的初始化,传传入参数 false 最终会传到 MessageQueue 的构造函数中。初始化完成后,接着调用 myLooper 方法将返回值赋给成员变量 sMainLooper,它也是一个 Looper 类型的成员变量,接着再来看一下 prepare 方法的实现,源码如下:
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 对象是存放在 sThreadLocal 成员变量里面的。线程创建 Looper 对象的工作是由 prepare 函数来完成的,而在创建 Looper 对象的时候,会同时创建一个消息队列 MessageQueue,保存在 Loop