2.3 心系两界的MessageQueue
卷I第5章介绍过,MessageQueue类封装了与消息队列有关的操作。在一个以消息驱动的系统中,最重要的两部分就是消息队列和消息处理循环。在Android 2.3以前,只有Java世界的居民有资格向MessageQueue中添加消息以驱动Java世界的正常运转,但从Android 2.3开始,MessageQueue的核心部分下移至Native层,让Native世界的居民也能利用消息循环来处理他们所在世界的事情。因此现在的MessageQueue心系Native和Java两个世界。
2.3.1 MessageQueue的创建
现在来分析MessageQueue是如何跨界工作的,其代码如下:
[—>MessageQueue.java:MessageQueue]
MessageQueue(){
nativeInit();//构造函数调用nativeInit,该函数由Native层实现
}
nativeInit函数的真正实现为android_os_MessageQueue_nativeInit,其代码如下:
[—>android_os_MessageQueue.cpp:android_os_MessageQueue_nativeInit]
static void android_os_MessageQueue_nativeInit(JNIEnv*env, jobject obj){
//NativeMessageQueue是MessageQueue在Native层的代表
NativeMessageQueue*nativeMessageQueue=new NativeMessageQueue();
……
//将这个NativeMessageQueue对象设置到Java层保存
android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue);
}
nativeInit函数在Native层创建了一个与MessageQueue对应的NativeMessageQueue对象,其构造函数如下:
[—>android_os_MessageQueue.cpp:NativeMessageQueue]
NativeMessageQueue:NativeMessageQueue(){
/*
代表消息循环的Looper也在Native层中出现了。根据消息驱动的知识,一个线程会有一个
Looper来循环处理消息队列中的消息。下面一行的调用就是取得保存在线程本地存储空间(Thread Local Storage)中的Looper对象
*/
mLooper=Looper:getForThread();
if(mLooper==NULL){
/*
如为第一次进来,则该线程没有设置本地存储,所以须先创建一个Looper,然后再将其保存到TLS中,这是很常见的一种以线程为单位的单例模式
*/
mLooper=new Looper(false);
Looper:setForThread(mLooper);
}
}
Native的Looper是Native世界中参与消息循环的一位重要角色。虽然它的类名和Java层的Looper类一样,但此二者其实并无任何关系。这一点以后还将详细分析。