[英]Issue calling back into Java from C++ called during a GLSurcfaceView callback
I have a GLSurfaceView created in a JAR file within my Android app. 我在Android应用程序的JAR文件中创建了GLSurfaceView。 In the GLSurfaceView callback for onDrawFrame, I call a native C++ method via JNI.
在onDrawFrame的GLSurfaceView回调中,我通过JNI调用了本机C ++方法。 At this point, I believe I am in the GLThread, and in that native method, I am trying to call back into a Java class in my App's namespace and NOT into the namespace which made the call.
在这一点上,我相信我在GLThread中,并且在该本机方法中,我试图在我应用程序的名称空间中调用Java类,而不是在进行调用的名称空间中进行调用。 So, I am trying to explicitly attach to the UI thread before doing so, but I am not successful.
因此,我试图在这样做之前显式地附加到UI线程,但是我没有成功。
I am receiving the following error 我收到以下错误
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)
My C++ code looks like : 我的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;
}
I am trying to call back into a Java class in my App's namespace and NOT into the namespace which made the call
我正在尝试在应用程序的命名空间中回调到Java类,而不是在进行调用的命名空间中回调
Yeah, that's the problem. 是的,就是这个问题。 You have looked up a methodID in class
com.main.myapp
but then you are trying to invoke that methodID on the original jobject instance of org.myorg.ImageRenderer
! 你已经看过了放在methodID类
com.main.myapp
但你试图调用上的原jobject实例放在methodID org.myorg.ImageRenderer
! If you want to invoke a method from another "namespace", you have several options: 如果要从另一个“命名空间”调用方法,则有以下几种选择:
Your function is called from Java, therefore you should not call AttachCurrentThread
. 您的函数是从Java调用的,因此您不应调用
AttachCurrentThread
。
Your function receives from Java a reference to the org.myorg.myRenderer
object, of which renderImageFrame() is a native method (every native method receives Java environment env
as the first parameter, and its object reference, often denoted as thiz
, as second parameter. 您的函数从Java接收到对
org.myorg.myRenderer
对象的引用,该对象的renderImageFrame()是本机方法(每个本机方法都将Java环境env
接收为第一个参数,其对象引用通常称为thiz
,作为第二个参数参数。
If you want to call a Java method updateView() for the app
object of class com.main.myapp
, you should first obtain a reference to this object. 如果你想调用Java方法的UpdateView()的
app
类的对象com.main.myapp
,你应该首先获得该对象的引用。 The easiest way is to pass it as argument to your function, so now it will be declared as 最简单的方法是将其作为参数传递给函数,因此现在将其声明为
JNIEXPORT void JNICALL Java_org_myorg_ImageRenderer_renderImageFrame(JNIEnv *env, jobject thiz, jobject app);
Alternatively, you may find the app
object from thiz
, if a reference to app
is a field of the org.myorg.myRenderer
, or is returend by some method of this class. 另外,如果对
app
的引用是org.myorg.myRenderer
的字段,或者被此类的某些方法所破坏,则可以从thiz
找到app
对象。
Finally, you are probably right, and calling an updateView()
method, which requires the UI thread, from a GL thread, is not a good idea. 最后,您可能是对的,从GL线程中调用需要UI线程的
updateView()
方法不是一个好主意。 You should probably issue a post
, or send a message, or simply call runOnUIThread()
. 您可能应该发布一个
post
,或者发送一条消息,或者干脆调用runOnUIThread()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.