【发布时间】:2019-09-03 12:55:02
【问题描述】:
我有一个本机代码,我想使用 JNI 从它调用一些 Java 方法,我的主要问题是 JVM env 的 FindClass 方法在我的类的情况下总是返回 null 尽管我写正确但如果有任何 Java像 String 这样的类它返回一个有效的指针,我得到了一个加载 ClassLoader 的示例代码,让它加载我的类,但不幸的是我得到了 NULL。
这是代码:
unsigned char* pixels = new unsigned char[3 * width * height];
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
std::string imgURL(dataPath+"/Levels/screenshot.png");
stbi_write_png(imgURL.c_str(), width, height, 3, pixels, width * 3);
stbi_image_free(pixels);
JNIEnv *lJNIEnv;
manager.activity->vm->AttachCurrentThread(&lJNIEnv, NULL);
jobject lNativeActivity = manager.activity->clazz;
jclass ClassNativeActivity = lJNIEnv->FindClass("android/app/NativeActivity");
jclass contextClass = lJNIEnv->FindClass("android/content/Context");
if(contextClass == 0)
return;
jmethodID startActivityMethodId = lJNIEnv->GetMethodID(contextClass, "startActivity", "(Landroid/content/Intent;)V");
if(startActivityMethodId == 0)
return;
jclass intentClass = lJNIEnv->FindClass("android/content/Intent");
if(intentClass == 0)
return;
jmethodID intentConstructorMethodId = lJNIEnv->GetMethodID(intentClass, "<init>", "()V");
if(intentConstructorMethodId == 0)
return;
jmethodID intentSetActionMethodId = lJNIEnv->GetMethodID(intentClass, "setAction", "(Ljava/lang/String;)Landroid/content/Intent;");
if(intentSetActionMethodId == 0)
return;
jmethodID getClassLoader = lJNIEnv->GetMethodID(ClassNativeActivity,"getClassLoader", "()Ljava/lang/ClassLoader;");
if(getClassLoader == 0)
return;
jobject cls = lJNIEnv->CallObjectMethod(lNativeActivity, getClassLoader);
if(cls == 0)
return;
jclass classLoader = lJNIEnv->FindClass("java/lang/ClassLoader");
if(classLoader == 0)
return;
jmethodID findClass = lJNIEnv->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
if(findClass == 0)
return;
jstring intentString = lJNIEnv->NewStringUTF("com/game/Share");
if(intentString == 0)
return;
jobject intentObject = lJNIEnv->NewObject(intentClass,intentConstructorMethodId);
if(intentObject == 0)
return;
//Here I got NULL although the package and class are correct
jclass marketActivityClass = (jclass)lJNIEnv->CallObjectMethod(cls, findClass, intentString);
if(marketActivityClass == 0)
return;
lJNIEnv->CallVoidMethod(intentObject, intentSetActionMethodId,intentString);
lJNIEnv->CallVoidMethod(lNativeActivity, startActivityMethodId, intentObject);
manager.activity->vm->DetachCurrentThread();
有什么帮助吗?
【问题讨论】:
-
你是说评论前的
GetMethodID()调用返回NULL,还是评论后的NewStringUTF()返回NULL? -
@zenzelezz 你是对的,我编辑了它,它是
CallObjectMethod -
你怎么知道你得到
NULL?请注意,如果出现错误,您没有正确分离当前线程。您如何获得manager.activity->clazz;的价值?也发一下。 -
见stackoverflow.com/questions/14586821/…。使用
NewStringUTF("com.game.Share")。 -
请注意,在分离线程之前必须释放所有本地引用。
标签: android c++ java-native-interface classloader