2012-12-20 52 views
5

我想從我的cpp類中調用我的java類中的一些函數。在第三次調用函數之前,我已經成功地完成了這些調用。我正在使用cocos2dx引擎。env-> FindClass函數返回null

我從MiscManagerJni.cpp

我收到以下錯誤調用函數MiscManager.java當我試圖讓,classid和遊戲崩潰:

12-20 12:06:09.328: W/System.err(26651): java.lang.NoClassDefFoundError: [generic] 12-20 12:06:09.328: W/System.err(26651): at dalvik.system.NativeStart.main(Native Method) 12-20 08:56:35.402: D/libMiscManager(25952): Failed to find class of com/games/Game/MiscManager

我已經成功地被調用函數的3倍MiscManager MiscManagerJni.cpp類中的.java類。但第四次空返回時,我打電話

jclass ret = pEnv->FindClass(CLASS_NAME);

有誰能告訴我是什麼原因導致此錯誤。

這是我使用的方法獲取的ID和類ID

#define LOG_TAG "libMiscManager" 
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) 
#define CLASS_NAME "com/games/Game/MiscManager" 

typedef struct JniMethodInfo_ 
{ 
    JNIEnv * env; 
    jclass  classID; 
    jmethodID methodID; 
} JniMethodInfo; 


extern "C" 

{ 
    // get env and cache it 
    static JNIEnv* getJNIEnv(void) 
    { 

    JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); 
    if (NULL == jvm) { 
     LOGD("Failed to get JNIEnv. JniHelper::getJavaVM() is NULL"); 
     return NULL; 
    } 

    JNIEnv *env = NULL; 
    // get jni environment 
    jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4); 

    switch (ret) { 
     case JNI_OK : 
      // Success! 

      return env; 

     case JNI_EDETACHED : 
      // Thread not attached 
      if (jvm->AttachCurrentThread(&env, NULL) < 0) 
      { 
       LOGD("Failed to get the environment using AttachCurrentThread()"); 
       return NULL; 
      } else { 
       // Success : Attached and obtained JNIEnv! 
       return env; 
      } 

     case JNI_EVERSION : 

      // Cannot recover from this error 
      LOGD("JNI interface version 1.4 not supported"); 
     default : 

      LOGD("Failed to get the environment using GetEnv()"); 
      return NULL; 
    } 
} 

// get class and make it a global reference, release it at endJni(). 
static jclass getClassID(JNIEnv *pEnv) 
{ 
    jclass ret = pEnv->FindClass(CLASS_NAME); 
    if (! ret) 
    { 
     LOGD("Failed to find class of %s", CLASS_NAME); 
    } 
    return ret; 
} 

static bool getStaticMethodInfo(cocos2d::JniMethodInfo &methodinfo, const char *methodName, const char *paramCode) 
{ 
    jmethodID methodID = 0; 
    JNIEnv *pEnv = 0; 
    bool bRet = false; 

    do 
    { 
     pEnv = getJNIEnv(); 
     if (! pEnv) 
     { 
      break; 
     } 

     jclass classID = getClassID(pEnv); 

     methodID = pEnv->GetStaticMethodID(classID, methodName, paramCode); 

     if (! methodID) 
     { 
      LOGD("Failed to find static method id of %s", methodName); 
      break; 
     } 
     methodinfo.classID = classID; 
     methodinfo.env = pEnv; 
     methodinfo.methodID = methodID; 

     bRet = true; 
    } while (0); 
    return bRet; 


    } 

void InitJni() 
     { 
     cocos2d::JniMethodInfo methodInfo; 
     if (! getStaticMethodInfo(methodInfo, "Init", "()V")) 
     { 
      return ; 
     } 

    methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID); 
    methodInfo.env->DeleteLocalRef(methodInfo.classID); 
} 

void SaveBooleanJni(const char *key, bool value) 
    { 
     cocos2d::JniMethodInfo methodInfo; 
     if (! getStaticMethodInfo(methodInfo, "SaveBoolean", "(Ljava/lang/String;Z)V")) 
     { 
     return; 
    } 

    jstring stringArg = methodInfo.env->NewStringUTF(key); 
    methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg, value); 
    methodInfo.env->DeleteLocalRef(stringArg); 
    methodInfo.env->DeleteLocalRef(methodInfo.classID); 
} 

void SaveIntegerJni(const char *key, int value) 
{ 
    cocos2d::JniMethodInfo methodInfo; 
    if (! getStaticMethodInfo(methodInfo, "SaveInteger", "(Ljava/lang/String;I)V")) 
    { 
     return; 
    } 

    jstring stringArg = methodInfo.env->NewStringUTF(key); 
    methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg, value); 
    methodInfo.env->DeleteLocalRef(stringArg); 
    methodInfo.env->DeleteLocalRef(methodInfo.classID); 
} 

void SaveLongJni(const char *key, long value) 
{ 
    cocos2d::JniMethodInfo methodInfo; 
    if (! getStaticMethodInfo(methodInfo, "SaveLong", "(Ljava/lang/String;J)V")) 
    { 
     return; 
    } 
    jstring stringArg = methodInfo.env->NewStringUTF(key); 
    methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg, value); 
    methodInfo.env->DeleteLocalRef(stringArg); 
    methodInfo.env->DeleteLocalRef(methodInfo.classID); 
} 

long GetLongJni(const char *key, long defaultValue) 
{ 
    cocos2d::JniMethodInfo methodInfo; 
    long ret = 0; 
    if (! getStaticMethodInfo(methodInfo, "GetInteger", "(Ljava/lang/String;J)J")) 
    { 
     return ret; 
    } 

    jstring stringArg = methodInfo.env->NewStringUTF(key); 
    ret = methodInfo.env->CallStaticLongMethod(methodInfo.classID, methodInfo.methodID, stringArg, defaultValue); 
    methodInfo.env->DeleteLocalRef(stringArg); 
    methodInfo.env->DeleteLocalRef(methodInfo.classID); 

    return (long)ret; 
} 

bool GetBooleanJni(const char *key, bool defaultValue) 
{ 
    cocos2d::JniMethodInfo methodInfo; 
    jboolean ret = false; 
    if (! getStaticMethodInfo(methodInfo, "GetBoolean", "(Ljava/lang/String;Z)Z")) 
    { 
     return ret; 
    } 
    jstring stringArg = methodInfo.env->NewStringUTF(key); 
    ret = methodInfo.env->CallStaticIntMethod(methodInfo.classID, methodInfo.methodID, stringArg, defaultValue); 
    methodInfo.env->DeleteLocalRef(stringArg); 
    methodInfo.env->DeleteLocalRef(methodInfo.classID); 

    return ret; 
} 

int GetIntegerJni(const char *key, int defaultValue) 
{ 
    cocos2d::JniMethodInfo methodInfo; 
    int ret = 0; 
    if (! getStaticMethodInfo(methodInfo, "GetInteger", "(Ljava/lang/String;I)I")) 
    { 
     return ret; 
    } 

    jstring stringArg = methodInfo.env->NewStringUTF(key); 
    ret = methodInfo.env->CallStaticIntMethod(methodInfo.classID, methodInfo.methodID, stringArg, defaultValue); 
    methodInfo.env->DeleteLocalRef(stringArg); 
    methodInfo.env->DeleteLocalRef(methodInfo.classID); 

    return (unsigned int)ret; 
} 

bool IsConnectedToNetworkJni() 
{ 
    cocos2d::JniMethodInfo methodInfo; 
    jboolean ret = false; 
    if (! getStaticMethodInfo(methodInfo, "IsConnectedToNetwork", "()Z")) 
    { 
     return ret; 
    } 

    ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID); 
    methodInfo.env->DeleteLocalRef(methodInfo.classID); 

    return ret; 
} 
} 
+0

getStaticMethodInfo(methodInfo,「SaveLong」,「(Ljava/lang/String; J)V」):其中是com/games/Game/MiscManager引用?對我來說,似乎缺少一個參數classname。 –

+0

對不起,我已經添加了其餘的功能,正如你所看到的,我已經定義了類名 – glo

+0

你能顯示適用於其他調用的代碼嗎?它似乎很奇怪,它失敗的類沒有找到,而我們期望的方法沒有找到問題或其他什麼... –

回答

0

我在cocos2dx引擎使用JNIHelper類解決了這個問題的功能。 我在JNIHelper類中使用了getStaticMethodInfo,而不是在我自己的類中寫入。