![](/img/trans.png)
[英]Calling a c++ callback from Java invoked from C++ application via JNI
[英]Issue calling back into Java from C++ called during a GLSurcfaceView callback
我在Android应用程序的JAR文件中创建了GLSurfaceView。 在onDrawFrame的GLSurfaceView回调中,我通过JNI调用了本机C ++方法。 在这一点上,我相信我在GLThread中,并且在该本机方法中,我试图在我应用程序的名称空间中调用Java类,而不是在进行调用的名称空间中进行调用。 因此,我试图在这样做之前显式地附加到UI线程,但是我没有成功。
我收到以下错误
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类,而不是在进行调用的命名空间中回调
是的,就是这个问题。 你已经看过了放在methodID类com.main.myapp
但你试图调用上的原jobject实例放在methodID org.myorg.ImageRenderer
! 如果要从另一个“命名空间”调用方法,则有以下几种选择:
您的函数是从Java调用的,因此您不应调用AttachCurrentThread
。
您的函数从Java接收到对org.myorg.myRenderer
对象的引用,该对象的renderImageFrame()是本机方法(每个本机方法都将Java环境env
接收为第一个参数,其对象引用通常称为thiz
,作为第二个参数参数。
如果你想调用Java方法的UpdateView()的app
类的对象com.main.myapp
,你应该首先获得该对象的引用。 最简单的方法是将其作为参数传递给函数,因此现在将其声明为
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()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.