繁体   English   中英

在GLSurcfaceView回调期间从C ++调用回Java的问题

[英]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类,而不是在进行调用的命名空间中回调

是的,就是这个问题。 你已经看过了放在methodIDcom.main.myapp但你试图调用上的原jobject实例放在methodID org.myorg.ImageRenderer 如果要从另一个“命名空间”调用方法,则有以下几种选择:

  1. 该方法必须是静态的,以便找到一个类就足够了,并且您不需要对象
  2. 另一个对象必须在本机方法中作为参数传递
  3. 另一个对象必须作为原始对象的成员/获取者(声明了您的本机方法)才能访问,然后可以通过JNI方法查找和调用来访问

您的函数是从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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM