JNI—由JNI自主调用Java方法
这是我关于stackoverflow的第一个问题,我的英语不是最好的。请您谅解:) 我试图通过JNI调用静态方法,但无法捕获JNIEnv。这个项目是在Android平台上运行的,使用eclipse,我无法调试 我使用的代码是:JNI—由JNI自主调用Java方法,java,android,java-native-interface,wrapper,cocos2d-x,Java,Android,Java Native Interface,Wrapper,Cocos2d X,这是我关于stackoverflow的第一个问题,我的英语不是最好的。请您谅解:) 我试图通过JNI调用静态方法,但无法捕获JNIEnv。这个项目是在Android平台上运行的,使用eclipse,我无法调试 我使用的代码是: void MyCClass::myCMethod() { int status; JNIEnv *env; bool isAttached = false; status = gJavaVM->GetEnv((void **) &a
void MyCClass::myCMethod()
{
int status;
JNIEnv *env;
bool isAttached = false;
status = gJavaVM->GetEnv((void **) &env, NULL); // CRASH HERE
if(status < 0) {
status = gJavaVM->AttachCurrentThread(&env, NULL);
if(status < 0) {
return;
}
isAttached = true;
}
if(env==NULL) {
return;
}
jclass handlerClass = env->FindClass("com/package/javaClass");
if(handlerClass==NULL) {
return;
}
jmethodID mid = env->GetMethodID(handlerClass, "TestCall", "()V");
if (mid == NULL) {
return;
}
env->CallVoidMethod(handlerClass, mid);
}
然后,在执行该操作的类中,必须将init()声明为OnLoad方法(),并使用class Controller对象保存JNIEnv类型的“env”
extern "C" {
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
cocos2d::CCLog("TESTE LOAD APPLICATION");
jint result = -1;
if (vm->GetEnv((void**) &Controller::Instance()->env, JNI_VERSION_1_4) != JNI_OK) {
cocos2d::CCLog("TESTE FAIL LOAD");
return result;
}
cocos2d::CCLog("Could not retrieve the env!");
//test(env);
cocos2d::CCLog("TESTE SUCCESS");
return JNI_VERSION_1_4;
}
}
从现在起,我们可以如下调用Java方法:
void AddChild::callFlagMenu()
{
jclass handlerClass = Controller::Instance()->env->FindClass("com/imobilemagic/mms/ui/AddChild/AddChild");
if(handlerClass==NULL) {
return;
}
jmethodID mid = Controller::Instance()->env->GetMethodID(handlerClass, "TestCall", "()V");
if (mid == NULL) {
return;
}
Controller::Instance()->env->CallVoidMethod(handlerClass, mid);
}
我希望我帮了忙!:) 您确定
gJava
不为空吗?这不是正确的解决方案。JNIEnv是特定于线程的,因此将其保存在单例中可能不正确。在所有JNI都发生在同一个线程中的情况下,它可能会起作用。
extern "C" {
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
cocos2d::CCLog("TESTE LOAD APPLICATION");
jint result = -1;
if (vm->GetEnv((void**) &Controller::Instance()->env, JNI_VERSION_1_4) != JNI_OK) {
cocos2d::CCLog("TESTE FAIL LOAD");
return result;
}
cocos2d::CCLog("Could not retrieve the env!");
//test(env);
cocos2d::CCLog("TESTE SUCCESS");
return JNI_VERSION_1_4;
}
}
void AddChild::callFlagMenu()
{
jclass handlerClass = Controller::Instance()->env->FindClass("com/imobilemagic/mms/ui/AddChild/AddChild");
if(handlerClass==NULL) {
return;
}
jmethodID mid = Controller::Instance()->env->GetMethodID(handlerClass, "TestCall", "()V");
if (mid == NULL) {
return;
}
Controller::Instance()->env->CallVoidMethod(handlerClass, mid);
}