I met a problem in my project using cocos2d-1.0.1-x-0.9.2 API on Android platform.
Calling to any function such as preloadBackgroundMusic and playBackgroundMusic in SimpleAudioEngine will cause a crash.
I found that actually calling to any function in class SimpleAudioEngine will cause a crash just at the very line “env~~>CallStaticVoidMethod;" where the global variable classOfCocos2dxActivity is NULL.
The questionable code is here:
<pre>
static jmethodID getMethodID
{
jmethodID ret = 0;
// get jni environment and java class for Cocos2dxActivity
if &env, JNI_VERSION_1_4) != JNI_OK)
{
LOGD (“Failed to get the environment using GetEnv()”);
return 0;
}
if < 0)
{
LOGD (“Failed to get the environment using AttachCurrentThread()”);
return 0;
}
classOfCocos2dxActivity = env~~>FindClass(”org/cocos2dx/lib/Cocos2dxActivity");
if (! classOfCocos2dxActivity)
{
LOGD (“Failed to find class of org/cocos2dx/lib/Cocos2dxActivity”);
return 0;
}
if (env = 0)
{
ret = env~~>GetStaticMethodID;
env~~>DeleteLocalRef(classOfCocos2dxActivity);
// *************************************************************************************************
// this line will release classOfCocos2dxActivity, but later, classOfCocos2dxActivity will be used again in preloadBackgroundMusicJNI
// by the line “env->CallStaticVoidMethod(classOfCocos2dxActivity, preloadBackgroundMusicMethodID, stringArg);”
//*************************************************************************************************
}
if (! ret)
{
LOGD (“get method id of %s error”, methodName);
}
return ret;
}
if (preloadBackgroundMusicMethodID)
{
jstring stringArg = env->NewStringUTF(path);
env->CallStaticVoidMethod(classOfCocos2dxActivity, preloadBackgroundMusicMethodID, stringArg);
// ************************************************************************
// above, classOfCocos2dxActivity is a NULL pointer which will cause crash in CallStaticVoidMethod
// ************************************************************************
env->DeleteLocalRef(stringArg);
}
}
For now, I have to fix this problem by following steps:
static jmethodID getMethodID(const char *methodName, const char *paramCode)
{
jmethodID ret = 0;
// get jni environment and java class for Cocos2dxActivity
if (gJavaVM->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK)
{
LOGD("Failed to get the environment using GetEnv()");
return 0;
}
if (gJavaVM->AttachCurrentThread(&env, 0) < 0)
{
LOGD("Failed to get the environment using AttachCurrentThread()");
return 0;
}
if (env == 0)
{ LOGD("Failed to get environment, env* = 0");
return 0;
}
// **************************************************************************************
if (!classOfCocos2dxActivity) classOfCocos2dxActivity = env->FindClass("org/cocos2dx/lib/Cocos2dxActivity"); // fix #1
// **************************************************************************************
if (! classOfCocos2dxActivity)
{
LOGD("Failed to find class of org/cocos2dx/lib/Cocos2dxActivity");
return 0;
}
ret = env->GetStaticMethodID(classOfCocos2dxActivity, methodName, paramCode);
LOGD("SimpleAudioEngine just got methodID: %d", ret);
//********************************************
//env->DeleteLocalRef(classOfCocos2dxActivity); // fix #2
//********************************************
if (! ret)
{
LOGD("get method id of %s error", methodName);
}
return ret;
}
Did anybody meet the same problem?