从C+调用回Java的问题+;在GLSurcfaceView回调期间调用
我在Android应用程序的JAR文件中创建了一个GLSURFACHEVIEW。在OnDrFrrFrand的GLSOLVEVIEW回调中,我通过JNI调用一个本地C++方法。 在这一点上,我相信我是在GLThread中,并且在该原生方法中,我试图调用回我的应用程序名称空间中的Java类,而不是名称空间 是谁打电话的。因此,我试图在这样做之前显式地附加到UI线程,但没有成功 我收到以下错误从C+调用回Java的问题+;在GLSurcfaceView回调期间调用,java,android,c++,java-native-interface,Java,Android,C++,Java Native Interface,我在Android应用程序的JAR文件中创建了一个GLSURFACHEVIEW。在OnDrFrrFrand的GLSOLVEVIEW回调中,我通过JNI调用一个本地C++方法。 在这一点上,我相信我是在GLThread中,并且在该原生方法中,我试图调用回我的应用程序名称空间中的Java类,而不是名称空间 是谁打电话的。因此,我试图在这样做之前显式地附加到UI线程,但没有成功 我收到以下错误 W/dalvikvm( 4243): JNI WARNING: can't call Lcom/main/m
W/dalvikvm( 4243): JNI WARNING: can't call Lcom/main/myapp;.updateView on instance of Lorg/myorg/myRenderer;
W/dalvikvm( 4243): in Lorg/myorg/ImageRenderer;.renderImageFrame:()V (CallVoidMethodV)
I/dalvikvm( 4243): "GLThread 336" prio=5 tid=16 RUNNABLE
I/dalvikvm( 4243): | group="main" sCount=0 dsCount=0 obj=0x418029f8 self=0x400988a8
I/dalvikvm( 4243): | sysTid=4268 nice=0 sched=0/0 cgrp=apps handle=1362099424
I/dalvikvm( 4243): | schedstat=( 0 0 0 ) utm=83 stm=71 core=1
I/dalvikvm( 4243): at org.myorg.ImageRenderer.renderImageFrame(Native Method)
I/dalvikvm( 4243): at org.myorg.ImageRenderer.onDrawFrame(ImageRenderer.java:93)
I/dalvikvm( 4243): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
I/dalvikvm( 4243): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
<>我的C++代码看起来像:
JavaVM * jvm;
JNIEXPORT void JNICALL Java_org_myorg_ImageRenderer_renderImageFrame
(JNIEnv *env, jobject jObj) {
jvm->AttachCurrentThread(&env, 0);
jclass javaClass = env->FindClass("com/main/myapp");
if(javaClass == NULL){
LOGD("ERROR - CANNOT FIND CLASS");
}
jfloatArray viewArray = env->NewFloatArray(16);
env->SetFloatArrayRegion(viewArray, 0, 16, glmatrix.data);
jmethodID method = env->GetMethodID(javaClass, "updateView", "([F)V");
if(method == NULL){
LOGD("ERROR - CANNOT ACCESS METHOD");
}
env->CallVoidMethod(jObj, method, viewArray);
env->DeleteLocalRef(viewArray);
jvm->DetachCurrentThread();
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
jvm = vm;
return JNI_VERSION_1_2;
}
我正在尝试调用我的应用程序名称空间中的Java类,然后
未进入发出调用的命名空间
是的,这就是问题所在。您已经在类com.main.myapp
中查找了一个methodID,但是您正在尝试在org.myorg.ImageRenderer
的原始jobject实例上调用该methodID!如果要从另一个“名称空间”调用方法,则有几个选项:
com.main.myapp
中查找了一个methodID,但是您正在尝试在org.myorg.ImageRenderer
的原始jobject实例上调用该methodID!如果要从另一个“名称空间”调用方法,则有几个选项:
您的函数是从Java调用的,因此不应调用
AttachCurrentThread
函数从Java接收对org.myorg.myRenderer
对象的引用,其中renderImageFrame()是一个本机方法(每个本机方法都接收Java environmentenv
作为第一个参数,其对象引用(通常表示为thiz
)作为第二个参数)
如果要为类com.main.myapp
的app
对象调用Java方法updateView(),应首先获取对该对象的引用。最简单的方法是将其作为参数传递给函数,因此现在它将声明为
JNIEXPORT void JNICALL Java_org_myorg_ImageRenderer_renderImageFrame(JNIEnv *env, jobject thiz, jobject app);
或者,如果对app
的引用是org.myorg.myRenderer
的一个字段,或者通过此类的某些方法返回,则可以从thiz
中找到app
对象
最后,您可能是对的,从GL线程调用需要UI线程的
updateView()
方法不是一个好主意。您可能应该发布post
,或者发送消息,或者只需调用runOnUIThread()
您的函数是从Java调用的,因此您不应该调用AttachCurrentThread
函数从Java接收对org.myorg.myRenderer
对象的引用,其中renderImageFrame()是一个本机方法(每个本机方法都接收Java environmentenv
作为第一个参数,其对象引用(通常表示为thiz
)作为第二个参数)
如果要为类com.main.myapp
的app
对象调用Java方法updateView(),应首先获取对该对象的引用。最简单的方法是将其作为参数传递给函数,因此现在它将声明为
JNIEXPORT void JNICALL Java_org_myorg_ImageRenderer_renderImageFrame(JNIEnv *env, jobject thiz, jobject app);
或者,如果对app
的引用是org.myorg.myRenderer
的一个字段,或者通过此类的某些方法返回,则可以从thiz
中找到app
对象
最后,您可能是对的,从GL线程调用需要UI线程的
updateView()
方法不是一个好主意。您可能应该发出post
,或者发送消息,或者只需调用runOnUIThread()
警告是关于调用updateModel(),您的代码似乎正在调用updateView(),因此它们没有完全对齐。错误消息是,该方法未在您要传递的对象(“this”指针)中定义。您可以尝试用GetObjectClass(jObj)替换FindClass()然后查看GetMethodID调用是否失败。抱歉,我之前复制粘贴了错误的消息。对其进行了编辑。而且,我最初尝试使用GetObjectClass()时遇到了相同的问题,这就是我切换到FindClass()的原因。无论哪种方式,它都可以获取/找到类和方法,只是无法调用该方法。您可能希望尝试帮助您实现这一点!您正在运行checkVirtualMethod()中的测试在CheckJNI.c.中,测试检查调用方法的对象是否是该方法声明类的实例。该对象是myRenderer,但updateView方法是在myapp中声明的。警告是关于调用updateModel(),您的代码似乎在调用updateView(),因此它们没有完全对齐。错误消息是,该方法未在您要传递的对象(“this”指针)中定义。您可以尝试使用GetObjectClass(jObj)替换FindClass(),并查看GetMethodID调用是否失败。抱歉,我之前复制粘贴了错误的消息。编辑了它。而且,我最初尝试使用GetObjectClass(),并且有相同的问题,这就是为什么我切换到FindClass()。无论哪种方式,它都可以获取/找到类和方法,只是无法调用