Android应用程序消息处理机制(Looper、Handler)分析(3)

移动开发 Android
函数prepareMainLooper做的事情其实就是在线程中创建一个Looper对象,这个Looper对象是存放在sThreadLocal成员变量里面的。成员变量sThreadLocal的类型为ThreadLocal,表示这是一个线程局部变量,即保证每一个调用了 prepareMainLooper函数的线程里面都有一个独立的Looper对象。

函数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(); 
 } 
 ...... 
 } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

它的初始化工作都交给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); 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

在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); 


  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

它主要就是在内部创建了一个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)); 
  } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

这里传进来的参数messageQueueObj即为我们前面在Java层创建的消息队列对象,而 gMessageQueueClassInfo.mPtr即表示在Java类MessageQueue中,其成员变量mPtr的偏移量,通过这个偏移量, 就可以把这个本地消息队列对象natvieMessageQueue保存在Java层创建的消息队列对象的mPtr成员变量中,这是为了后续我们调用 Java层的消息队列对象的其它成员函数进入到JNI层时,能够方便地找回它在JNI层所对应的消息队列对象。

责任编辑:闫佳明 来源: bbs.9ria
相关推荐

2014-05-22 15:00:16

Android消息处理机制Looper

2014-05-22 15:07:44

Android消息处理机制Looper

2014-05-22 15:38:27

Android消息处理机制Looper

2014-05-22 15:41:59

Android消息处理机制Looper

2014-05-22 15:48:50

Android消息处理机制Looper

2014-05-22 14:57:28

Android消息处理机制Looper

2014-05-22 15:15:53

Android消息处理机制Looper

2014-05-22 15:18:25

Android消息处理机制Looper

2014-05-22 15:33:31

Android消息处理机制Looper

2014-05-22 15:45:58

Android消息处理机制Looper

2011-04-28 11:01:40

Android消息处理LooperHandler

2011-11-23 09:33:45

HandlerLooperMessage

2014-05-27 10:13:57

移动技术半月刊

2016-10-21 13:03:18

androidhandlerlooper

2011-09-05 17:40:40

MTK定时器

2011-03-17 09:20:05

异常处理机制

2021-08-12 16:28:10

AndroidHandleLooper

2023-03-08 08:54:59

SpringMVCJava

2023-06-15 14:09:00

解析器Servlet容器

2011-07-01 14:20:59

Qt 事件
点赞
收藏

51CTO技术栈公众号