OSDN Git Service

Optimize Looper JNI code.
authorJeff Brown <jeffbrown@google.com>
Mon, 28 Jan 2013 22:25:53 +0000 (14:25 -0800)
committerJeff Brown <jeffbrown@google.com>
Mon, 28 Jan 2013 22:25:53 +0000 (14:25 -0800)
Use static native methods.

Release the native looper objects as soon as the Looper quits
instead of waiting until the GC finalizer to take care of it.

Change-Id: I02783e48782a8f972ec2138862f700ade33d8e78

core/java/android/os/MessageQueue.java
core/jni/android_os_MessageQueue.cpp
services/jni/com_android_server_input_InputManagerService.cpp

index 5ad60ec..222578a 100644 (file)
@@ -48,10 +48,10 @@ public class MessageQueue {
     // Barriers are indicated by messages with a null target whose arg1 field carries the token.
     private int mNextBarrierToken;
 
-    private native void nativeInit();
-    private native void nativeDestroy();
-    private native void nativePollOnce(int ptr, int timeoutMillis);
-    private native void nativeWake(int ptr);
+    private native static int nativeInit();
+    private native static void nativeDestroy(int ptr);
+    private native static void nativePollOnce(int ptr, int timeoutMillis);
+    private native static void nativeWake(int ptr);
 
     /**
      * Callback interface for discovering when a thread is going to block
@@ -102,18 +102,25 @@ public class MessageQueue {
 
     MessageQueue(boolean quitAllowed) {
         mQuitAllowed = quitAllowed;
-        nativeInit();
+        mPtr = nativeInit();
     }
 
     @Override
     protected void finalize() throws Throwable {
         try {
-            nativeDestroy();
+            dispose();
         } finally {
             super.finalize();
         }
     }
 
+    private void dispose() {
+        if (mPtr != 0) {
+            nativeDestroy(mPtr);
+            mPtr = 0;
+        }
+    }
+
     final Message next() {
         int pendingIdleHandlerCount = -1; // -1 only during first iteration
         int nextPollTimeoutMillis = 0;
@@ -126,6 +133,7 @@ public class MessageQueue {
 
             synchronized (this) {
                 if (mQuiting) {
+                    dispose();
                     return null;
                 }
 
index a4dcac6..7540645 100644 (file)
@@ -109,55 +109,34 @@ void NativeMessageQueue::wake() {
 
 // ----------------------------------------------------------------------------
 
-static NativeMessageQueue* android_os_MessageQueue_getNativeMessageQueue(JNIEnv* env,
-        jobject messageQueueObj) {
+sp<MessageQueue> android_os_MessageQueue_getMessageQueue(JNIEnv* env, jobject messageQueueObj) {
     jint intPtr = env->GetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr);
     return reinterpret_cast<NativeMessageQueue*>(intPtr);
 }
 
-static void android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject messageQueueObj,
-        NativeMessageQueue* nativeMessageQueue) {
-    env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr,
-             reinterpret_cast<jint>(nativeMessageQueue));
-}
-
-sp<MessageQueue> android_os_MessageQueue_getMessageQueue(JNIEnv* env, jobject messageQueueObj) {
-    NativeMessageQueue* nativeMessageQueue =
-            android_os_MessageQueue_getNativeMessageQueue(env, messageQueueObj);
-    return nativeMessageQueue;
-}
-
-static void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) {
+static jint android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {
     NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
     if (!nativeMessageQueue) {
         jniThrowRuntimeException(env, "Unable to allocate native queue");
-        return;
+        return 0;
     }
 
     nativeMessageQueue->incStrong(env);
-    android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue);
+    return reinterpret_cast<jint>(nativeMessageQueue);
 }
 
-static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jobject obj) {
-    NativeMessageQueue* nativeMessageQueue =
-            android_os_MessageQueue_getNativeMessageQueue(env, obj);
-    if (nativeMessageQueue) {
-        android_os_MessageQueue_setNativeMessageQueue(env, obj, NULL);
-        nativeMessageQueue->decStrong(env);
-    }
-}
-
-static void throwQueueNotInitialized(JNIEnv* env) {
-    jniThrowException(env, "java/lang/IllegalStateException", "Message queue not initialized");
+static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jclass clazz, jint ptr) {
+    NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
+    nativeMessageQueue->decStrong(env);
 }
 
-static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
+static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jclass clazz,
         jint ptr, jint timeoutMillis) {
     NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
     nativeMessageQueue->pollOnce(env, timeoutMillis);
 }
 
-static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint ptr) {
+static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jint ptr) {
     NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
     return nativeMessageQueue->wake();
 }
@@ -166,8 +145,8 @@ static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint pt
 
 static JNINativeMethod gMessageQueueMethods[] = {
     /* name, signature, funcPtr */
-    { "nativeInit", "()V", (void*)android_os_MessageQueue_nativeInit },
-    { "nativeDestroy", "()V", (void*)android_os_MessageQueue_nativeDestroy },
+    { "nativeInit", "()I", (void*)android_os_MessageQueue_nativeInit },
+    { "nativeDestroy", "(I)V", (void*)android_os_MessageQueue_nativeDestroy },
     { "nativePollOnce", "(II)V", (void*)android_os_MessageQueue_nativePollOnce },
     { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake }
 };
index a97becf..57803e3 100644 (file)
@@ -975,6 +975,11 @@ void NativeInputManager::loadPointerResources(PointerResources* outResources) {
 static jint nativeInit(JNIEnv* env, jclass clazz,
         jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
+    if (messageQueue == NULL) {
+        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
+        return 0;
+    }
+
     NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
             messageQueue->getLooper());
     im->incStrong(serviceObj);