访问过时的本地引用,将 short[] 从 JNI 传递到 Java
Accessed stale local reference passing short[] from JNI to Java
您好,我正在使用 Java 和 JNI 为 Android 编写程序。
我正在缓存 JavaVM*,全局引用 jclass
和 onLoad()
中的 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
希望对您有所帮助
您好,我正在使用 Java 和 JNI 为 Android 编写程序。
我正在缓存 JavaVM*,全局引用 jclass
和 onLoad()
中的 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
希望对您有所帮助