Android應用程序消息處理機制(Looper、Handler)分析(3)
函數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層所對應的消息隊列對象。