分析的源码基于2.3版本
1、 Android应用程序在启动的时候,会在进程中加载ActivityThread类,并执行这个类的main函数,应用程序的消息循环就是在这个main函数里面实现的。
2、ActivityThread类的main函数做了两件事情:一是在主线程中创建了一个ActivityTread实例,二是通过Looper类使主线程进入消息循环中。
3、frameworks/base/core/java/android/os/Looper.java文件中的prepareMainLooper函数被ActivityThread的main函数调用。prepareMainLooper函数做的事情其实是在线程中创建一个Looper对象,这个Looper对象存放在sThreadLocal成员变量中。成员变量sThreadLocal是一个线程局部变量,保证每一个调用了prepareMainLooper函数的线程里面都有一个独立的Looper对象。Looper对象的创建工作是由Looper.java中的prepare函数完成的,而创建Looper对象的时候,会同时创建一个消息队列MessageQueue,保存在Looper的成员变量mQueue中,后续消息就是存放在这个队列中去。这里讲到的Looper和MessageQueue都是Java层的。
4、frameworks/base/core/java/android/os/MessageQueue.java中,其构造函数调用nativeInit函数完成初始化工作,但nativeInit的实现都交给了JNI层来做。对应的JNI文件为frameworks/base/core/jni/android_os_MessageQueue.cpp
在JNI的nativeInit中创建了一个JNI层的消息队列NativeMessageQueue对象,该对象的构造函数中有创建了一个Looper对象,这个Looper对象是JNI 成的,与上层Java层的Looper对应。
JNI层的nativeInit函数全名为androd_os_MessageQueue_nativeInit,它在创建了本地消息队列NativeMessageQueue后,接着调用android_os_MessageQueue_setNativeMessage函数,把这个消息队列对象保存到Java层创建的MessageQueue对象的成员变量mPtr中。
5、Looper类的JNI实现在frameworks/base/libs/utils/Looper.cpp,这里的Looper对象创建了一个管道(包括读和写),以及使用了epoll机制,epoll机制是用来唤醒读线程的。
稍微补充一下Looper和Handler的知识:
Looper:封装了一个消息队列和消息循环
Handler:其实可以看作是一个工具,往消息队列里插入消息
Looper、Handler、MessageQueue和Message的关系:
Handler在Looper中的MessageQueue里插入Message,Looper获取到Message后,调用Handler的dispatchMessage来分发和处理消息。