我在解决这个问题时遇到了令人沮丧的时间,而且JNI文档非常稀少。非常感谢协助!
我在Android网络应用上分配了一个项目。本机端存储有关您连接的用户的信息,我需要将此用户列表发送到Java端以更新UI信息。基本上我需要组成一个字符串数组和一个布尔数组,其中包含已连接用户的名称和标志,但稍后可能会发送更多信息。我的困难在于释放&清理包含String信息的Object数组。我不清楚如何做到这一点。这就是我所拥有的:
void name_list_cb(struct user_info* user_list, size_t count, void *userdata)
{
jobject callbacks = (jobject)userdata;
JNIEnv *env;
(*g_vm)->GetEnv(g_vm, (void**)&env, JNI_VERSION_1_4);
jclass cls = (*env)->GetObjectClass(env, callbacks);
jmethodID method = (*env)->GetMethodID(env, cls, "user_list", "([Ljava/lang/String;[Z)V");
int i;
jobjectArray name_list;
jbooleanArray connected_list;
name_list = (jobjectArray)(*env)->NewObjectArray(env, count, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, ""));
connected_list = (jbooleanArray)(*env)->NewBooleanArray(env, count);
uint8_t boolean_arr[count];
for(i = 0; i < count; i++) {
(*env)->SetObjectArrayElement(env, name_list, i, (*env)->NewStringUTF(env, user_list[i].name));
boolean_arr[i] = user_list[i].connected;
}
(*env)->SetBooleanArrayRegion(env, connected_list, 0, count, (jboolean *)boolean_arr);
(*env)->CallVoidMethod(env, callbacks, method, name_list, connected_list);
(*env)->ReleaseBooleanArrayElements(env, connected_list, (jboolean *)boolean_arr, 0);
for(i = 0; i < count; i++) {
(*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, name_list, i), user_list[i].name);
//(*env)->ReleaseObjectArrayElements(env, name_list, count, 0);
}
(*env)->DeleteLocalRef(env, boolean_arr);
(*env)->DeleteLocalRef(env, name_list);
(*env)->DeleteLocalRef(env, connected_list);
(*env)->DeleteLocalRef(env, cls);
}
我得到“引用表溢出”或“信号11(SIGSEGV),故障地址deadbaad”。溢出/ memleak是主要问题。基本上我没有发布UTFChars和Object元素。虽然我在网上看过它的引用,但我的JNI版本没有ReleaseObjectArrayElement [s]。我一直在研究如何做到这一点但到目前为止没有运气!
答案 0 :(得分:1)
我认为问题是(* env) - &gt; DeleteLocalRef(env,boolean_arr);因为boolean_arr是C函数堆栈变量。
答案 1 :(得分:0)
typedef jarray jobjectArray;
void (*DeleteLocalRef)(JNIEnv*, jobject);
所以我认为使用DeleteLocalRef可以释放jobjectArray。 或者你可以在初始化方法中新建一次jobjectArray。