2015-07-13 74 views
0

我想獲得一個第三方庫類的構造函數,如「android.util.Size」。但由於某種原因,當我試圖從android核心庫中查詢字段或方法ID時,我返回NULL。任何想法爲什麼?第三方庫的JNI GetMethodID返回NULL

#include <stdio.h> 
#include <android/log.h> 
#include <jni.h> 

#define LOG(LOG_TAG,...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) 
#define LOGE(LOG_TAG,...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) 
#define TAG "TEST" 

#define CLS_SIZE "android/util/Size" 
int register_SizeStruct(JNIEnv* env){ 
    LOG(TAG, "Registering Size"); 
    jclass clazz = (jclass) env->NewGlobalRef(env->FindClass(CLS_SIZE)); 
    jmethodID init = env->GetMethodID(clazz, "<init>", " (II)V"); 

    if (clazz == NULL) LOGE(TAG, "Couldn't Register class " CLS_SIZE); 
    if (init == NULL) LOGE(TAG, "Couldn't Register Contructor for " CLS_SIZE); 

    if((clazz == NULL) || (init == NULL)) { 
     LOGE(TAG, "ERROR-Couldn't register Size struct"); 
     return -1; 
    } 
    return 0; 
} 

jint JNI_OnLoad(JavaVM* aVm, void* aReserved) 
{ 
    JNIEnv* env; 
    if (aVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK){ 
     LOGE (TAG, "Failed to get JNI_1_6 environment"); 
     return -1; 
    } 
    register_SizeStruct(env); 
    return JNI_VERSION_1_6; 
} 

這裏的日誌

I/TEST(2532): Registering Size 
E/TEST(2532): Couldn't Register Contructor for android/util/Size 
E/TEST(2532): ERROR-Couldn't register Size struct 
D/AndroidRuntime(2532): Shutting down VM 
E/AndroidRuntime(2532): FATAL EXCEPTION: main 
E/AndroidRuntime(2532): Process: com.example.testapp, PID: 2532 
E/AndroidRuntime(2532): java.lang.NoSuchMethodError: no non-static method "Landroid/util/Size;.<init> (II)V" 
E/AndroidRuntime(2532): at java.lang.Runtime.nativeLoad(Native Method) 
E/AndroidRuntime(2532): at java.lang.Runtime.doLoad(Runtime.java:428) 
E/AndroidRuntime(2532): at java.lang.Runtime.loadLibrary(Runtime.java:369) 
E/AndroidRuntime(2532): at java.lang.System.loadLibrary(System.java:989) 
E/AndroidRuntime(2532): at com.example.testapp.MainActivity.<clinit>(MainActivity.java:38) 
E/AndroidRuntime(2532): at java.lang.reflect.Constructor.newInstance(Native Method) 
E/AndroidRuntime(2532): at java.lang.Class.newInstance(Class.java:1572) 
E/AndroidRuntime(2532): at android.app.Instrumentation.newActivity(Instrumentation.java:1065) 
E/AndroidRuntime(2532): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199) 
E/AndroidRuntime(2532): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) 
E/AndroidRuntime(2532): at android.app.ActivityThread.access$800(ActivityThread.java:144) 
E/AndroidRuntime(2532): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) 
E/AndroidRuntime(2532): at android.os.Handler.dispatchMessage(Handler.java:102) 
E/AndroidRuntime(2532): at android.os.Looper.loop(Looper.java:135) 
E/AndroidRuntime(2532): at android.app.ActivityThread.main(ActivityThread.java:5221) 
E/AndroidRuntime(2532): at java.lang.reflect.Method.invoke(Native Method) 
E/AndroidRuntime(2532): at java.lang.reflect.Method.invoke(Method.java:372) 
E/AndroidRuntime(2532): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
+0

當你從這些方法中得到零時,使用'CheckException()'和朋友提供的異常信息不要只編寫自己的消息。這個問題的道德不是設計你自己的JNI方法簽名。使用'javap -s'的輸出。這絕不是錯的。 – EJP

回答

1

你有你的簽名字符串一個空間,不應該存在:

jmethodID init = env->GetMethodID(clazz, "<init>", " (II)V"); 
                ^-- RIGHT THERE 

刪除空間。同時也要確保你在API版本21或更高版本的Android版本上運行此版本,因爲這是添加了android.util.Size的地方。