访问过时的本地引用,将 short[] 从 JNI 传递到 Java

Accessed stale local reference passing short[] from JNI to Java

您好,我正在使用 Java 和 JNI 为 Android 编写程序。

我正在缓存 JavaVM*,全局引用 jclassonLoad() 中的 2 methodsID

然后从 myCallback(),即在单独线程上的 运行,我使用 AttachCurrentThread() 和已兑现的 JavaVM* 获取对环境的引用。 然后我想将 short[] 传递回 Java。

我收到错误:"accessed stale local reference"

这是我的代码:

JavaVM* mVm = NULL;
static jclass globalJavaReceiver = NULL;
jmethodID updatePlayerStatus = NULL;
jmethodID sendWaveData = NULL;

jint JNI_OnLoad(JavaVM* vm, void* reserved) {

    mVm = vm;

    JNIEnv* env;
    jclass nativeReceiver = NULL;

    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }

    nativeReceiver = (*env)->FindClass(env,
            "com/example/customviewcircles/nativeaudio/NativeReceiver");

    if (nativeReceiver != NULL) {

        globalJavaReceiver = (jclass)(*env)->NewGlobalRef(env, nativeReceiver);

        if (globalJavaReceiver != NULL) {

            updatePlayerStatus = (*env)->GetMethodID(env, globalJavaReceiver,
                    "myMethodName", "(I)V");

            sendWaveData = (*env)->GetMethodID(env, globalJavaReceiver,
                    "mySecondMethosName", "([S)V");
        }
    }
    return JNI_VERSION_1_6;
}

void myCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {

        JNIEnv* env;

        (*mVm)->AttachCurrentThread(mVm, &env, NULL);

        jshortArray javaArray = (*env)->NewShortArray(env, myBufferSize);
        if (javaArray != NULL) {

            (*env)->SetShortArrayRegion(env, javaArray, 0, myBufferSize,
                    myNativeShortArray);

        } 

        jobject myObject = NULL;

        if (globalJavaReceiver != NULL) {

            if (sendWaveData != NULL) {

                myObject = (*env)->NewObject(env, globalJavaReceiver,
                        sendWaveData);

                if (myObject != NULL) {

                    (*env)->CallVoidMethod(env, myObject, sendWaveData,
                            javaArray);

                    // getting error 
                    // JNI ERROR (app bug): accessed stale local reference 0x40995ec1 (index 22448 in a table of size 2)
                    // VM aborting
                    // A/libc(9813): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 9840 (AudioRecord)
                }
            }
        }
        (*mVm)->DetachCurrentThread(mVm);

}

我做错了什么?

感谢您的宝贵时间

这里的问题是:

  myObject = (*env)->NewObject(env, globalJavaReceiver,
                    sendWaveData);

我试图从错误的 class 函数创建对象,而不是从构造函数

然后我将这部分更改为:

myObject = (*env)->NewObject(env, globalJavaReceiver,
                nativeReceiverConstructor);

其中 nativeReceiverConstructor 是来自 class 构造函数的 jmethodID。然后我终于能够做到:

(*env)->CallVoidMethod(env, myObject, sendWaveData, javaArray);

其中 sendWaveData 是我要调用的函数的 jmethodID。

为了传递数组,我创建了一个 jshortArray 和 SetShortArrayRegion

希望对您有所帮助