2012-12-20 35 views
5

Tôi đang cố gắng gọi một số chức năng trong lớp java của tôi từ lớp cpp của tôi. Tôi thành công trong việc thực hiện các cuộc gọi này ba lần cho đến khi tôi gọi một chức năng lần thứ tư. Tôi đang sử dụng động cơ cocos2dx.env-> FindClass chức năng trả về null

tôi gọi hàm trong MiscManager.java từ MiscManagerJni.cpp

tôi nhận được lỗi sau khi tôi cố gắng để có được classID và trò chơi tai nạn:

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

Tôi đã gọi là thành công chức năng 3 lần trong MiscManager lớp .java từ lớp MiscManagerJni.cpp. Nhưng lần thứ 4 null được trả về khi tôi gọi

jclass ret = pEnv->FindClass(CLASS_NAME);

Bất cứ ai có thể cho tôi biết nguyên nhân gây ra lỗi này.

Đây là những chức năng tôi đang sử dụng để có được id phương pháp và lớp 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"): tham chiếu com/games/Game/MiscManager ở đâu? Đối với tôi, có vẻ như một tên lớp đối số bị thiếu. –

+0

xin lỗi tôi đã thêm phần còn lại của các chức năng và bạn có thể thấy tôi đã xác định tên lớp – glo

+0

bạn có thể hiển thị mã hoạt động cho các cuộc gọi khác không? nó có vẻ lạ rằng nó không thành công trên lớp không tìm thấy, trong khi chúng tôi mong đợi một vấn đề về phương pháp không tìm thấy hoặc cái gì khác ... –

Trả lời

0

tôi giải quyết vấn đề bằng cách sử dụng lớp JNIHelper trong công cụ cocos2dx. Tôi đã sử dụng getStaticMethodInfo trong lớp JNIHelper thay vì viết trong lớp của riêng tôi.