我正在使用Visual Studio模板将现有的C ++游戏移植到Android NDK。我已经到达了实现功能的阶段,该功能需要通过Java进行路由,而且我无法获得运行时来允许从C ++代码到JVM的调用。
我有一个Java类JNIActivityBridge,它扩展了NativeActivity并提供了一些有用的代码。通过onCreate,我可以调用C ++本机函数,而该函数又可以无缝地调用Java。我已使用它来验证我的基本JNI代码正确无误,并且我一直在为此特殊垫片填充的所有内容都可以正常工作。
//everything here works totally fine and I have no problems
JNIEXPORT void JNICALL Java_com_kata_JNIActivityBridge_InitializeJNIStuff(JNIEnv * env, jobject obj)
{
JniEnv = env;
ActivityBridge = obj;
PlatformSupportClass = env->FindClass("com/kata/PlatformSupport");
ActivityBridgeClass = env->FindClass("com/kata/JNIActivityBridge");
TestMethod = env->GetMethodID(ActivityBridgeClass, "AlertTest", "()V");
env->CallVoidMethod(ActivityBridge, TestMethod);
LOGI("JNI Active");
return;
}
我无法工作的是从主应用程序线程进行的任何JNI调用(将其调用栈追溯到android_main的代码)。我已经调用AttachCurrentThread,但是FindClass失败,如果我使用从活动填充程序缓存的jclass,则GetMethodID失败,当然我也不能调用Java。在这一点上,我只需要在游戏运行时调用一些简单的Java函数,就无法终生搞清楚如何从主线程重新进入JVM。要在此线程/上下文中使用Java函数,我需要什么?
void android_main(struct android_app* state) {
struct engine engine;
memset(&engine, 0, sizeof(engine));
state->userData = &engine;
state->onAppCmd = engine_handle_cmd;
state->onInputEvent = engine_handle_input;
engine.app = state;
AppEngine = &engine;
Jvm = state->activity->vm;
state->activity->vm->AttachCurrentThread(&engine.jni, nullptr);
//--- none of the following calls work here ---
jclass cl = engine.jni->FindClass("com/kata/PlatformSupport");
jmethodID mt = engine.jni->GetStaticMethodID(cl, "TestCallAdd", "(I)I");
jint add = engine.jni->CallStaticIntMethod(cl, mt, 3);
if(state->savedState != NULL) {
// We are starting with a previous saved state; restore from it.
engine.state = *(struct saved_state*)state->savedState;
}
GameMain(0, 0);
}