函数prepareMainLooper做的事情其实就是在线程中创建一个Looper对象,这个Looper对象是存放在sThreadLocal成员变量里面的。
成员变量sThreadLocal的类型为ThreadLocal,表示这是一个线程局部变量,即保证每一个调用了 prepareMainLooper函数的线程里面都有一个独立的Looper对象。
在线程是创建Looper对象的工作是由prepare函数来完成的,而在创建Looper对象的时候,会同时创建一个消息队列MessageQueue,保存在Looper的成员变量mQueue中,后续消息就是存放 在这个队列中去。
消息队列在Android应用程序消息处理机制中最重要的组件,因此,我们看看它的创建过程,即它的构造函数的实现。
实现 frameworks/base/core/java/android/os/MessageQueue.java文件中:
- [java] view plaincopypublic class MessageQueue {
- ......
- private int mPtr; // used by native code
- private native void nativeInit();
- MessageQueue() {
- nativeInit();
- }
- ......
- }
它的初始化工作都交给JNI方法nativeInit来实现了,这个JNI方法定义在frameworks/base/core/jni/android_os_MessageQueue.cpp文件中:
- [cpp] view plaincopystatic void android_os_MessageQueue_nativeInit(JNIEnv*
- env, jobject obj) {
- NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
- if (! nativeMessageQueue) {
- jniThrowRuntimeException(env, "Unable to allocate native queue");
- return;
- }
- android_os_MessageQueue_setNativeMessageQueue(env, obj,
- nativeMessageQueue);
- }
在JNI中,也相应地创建了一个消息队列NativeMessageQueue,NativeMessageQueue类也是定义在 frameworks/base/core/jni/android_os_MessageQueue.cpp文件中,它的创建过程如下所示:
- [cpp] view plaincopyNativeMessageQueue::NativeMessageQueue() {
- mLooper = Looper::getForThread();
- if (mLooper == NULL) {
- mLooper = new Looper(false);
- Looper::setForThread(mLooper);
- }
- }
它主要就是在内部创建了一个Looper对象,注意,这个Looper对象是实现在JNI层的,它与上面Java层中的Looper是不一样的,不过它们是对应的,下面我们进一步分析消息循环的过程的时候,读者就会清楚地了解到它们之间的关系。
这个Looper的创建过程也很重要,不过我们暂时放一放,先分析完android_os_MessageQueue_nativeInit函数的执 行,它创建了本地消息队列NativeMessageQueue对象之后,接着调用 android_os_MessageQueue_setNativeMessageQueue函数来把这个消息队列对象保存在前面我们在Java层中创 建的MessageQueue对象的mPtr成员变量里面:
- [cpp] view plaincopystatic void
- android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject
- messageQueueObj,
- NativeMessageQueue* nativeMessageQueue) {
- env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr,
- reinterpret_cast(nativeMessageQueue));
- }
这里传进来的参数messageQueueObj即为我们前面在Java层创建的消息队列对象,而 gMessageQueueClassInfo.mPtr即表示在Java类MessageQueue中,其成员变量mPtr的偏移量,通过这个偏移量, 就可以把这个本地消息队列对象natvieMessageQueue保存在Java层创建的消息队列对象的mPtr成员变量中,这是为了后续我们调用 Java层的消息队列对象的其它成员函数进入到JNI层时,能够方便地找回它在JNI层所对应的消息队列对象。