【发布时间】:2015-04-08 13:50:23
【问题描述】:
我有类似的 jni cpp 类
JNIEXPORT void JNICALL Java_com_my_package_GameBridge_startGame(JNIEnv *env,
jobject obj))
{
GameBridge_Android gameBridge;
JavaVM* jvm;
int status = env->GetJavaVM(&jvm);
// global reference
jobject globalRef = env->NewGlobalRef(obj)
gameBridge.setCallback(globalRef);
gameBridge.startGame();
}
我正在尝试将 jobject 的引用存储为全局引用,并且只要我需要,我就可以在该对象上调用 java 方法。
我决定创建纯 c++ 类 - GameBridge_Android
C++ 标头与此类似
GameBridge_Android.h:
class GameBridge_Android : public GameBridge
{
public:
GameBridge_Android();
virtual void startGame();
virtual void restartGame();
virtual void pauseGame();
virtual void resumeGame();
virtual void setCallback(jobject obj);
protected:
jobject mCallback;
};
及其实现
GameBridge_Android.cpp:
void GameBridge_Android::restartGame(){//....}
void GameBridge_Android::resumeGame(){//....}
void GameBridge_Android::setCallback(jobject callback)
{
mCallback = callback;
}
void GameBridge_Android::pauseGame()
{
JavaVM* vm = JniHelper::getJavaVM();
JNIEnv* env;
jint rs = vm->AttachCurrentThread(&env, NULL);
jclass cls = env->FindClass("com/my/package/GameBridge");
jmethodID onPause = env->GetMethodID(cls, "onPause", "()V");
env->CallVoidMethod(mCallback, onPause);
}
还有简单的java GameBridge 类
public class GameBridge {
public native void startGame();
public void onPause() {
Log.d("JAVA_GameBridge", "onPause called ");
}
}
我遇到了一个错误
art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: native code passing in reference to invalid global reference: 0x736c6576
04-08 16:33:57.889 25537-29355/com.my.package A/art﹕ art/runtime/check_jni.cc:65] in call to CallVoidMethodV
我尝试将 jobject 引用更改为全局引用,但没有成功(可能我在这里做错了) 但是,当我调用静态 java 方法时,一切正常。
附:我不是 C++ 开发人员,因此非常感谢您对此部分的任何建议和更正。
【问题讨论】:
-
为什么gameBridge是Java_com_my_package_GameBridge_startGame()中的一个局部变量?当函数完成时,它将被销毁
-
@samgak 你是对的,将游戏桥作为静态变量可能会更好。
-
那么,你找到解决这个问题的方法了吗?
-
@RenatoUtsch 不要在本机内存中保留对非静态 java 对象的引用。 Android 的 VM(Dalvik 或 ART)可以对对象做任何他们想做的事情(移动对象、垃圾等),因此无法保证引用会指向您期望的对象。
标签: android c++ cocos2d-iphone java-native-interface