将字符串数组列表从 Native java 返回到 JNI
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33406527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Returning an arraylist of string from Native java to JNI
提问by SACH
ArrayList<String> myArraylist;
public ArrayList<String> getData(){
myArraylist = new ArrayList<String>();
myArraylist.add("1267982563");
myArraylist.add("2345678");
myArraylist.add("5432789");
return myArraylist;
}
How to get the each items from the above method in JNI side and Push to vector and return from the JNI to other CPP calls in the JNI layer.
如何在JNI端从上面的方法中获取每个items并Push to vector并从JNI返回到JNI层中的其他CPP调用。
回答by Alex Cohn
Convert ArrayList to std::vector<std::string>:
将 ArrayList 转换为 std::vector<std::string>:
static jclass java_util_ArrayList;
static jmethodID java_util_ArrayList_;
jmethodID java_util_ArrayList_size;
jmethodID java_util_ArrayList_get;
jmethodID java_util_ArrayList_add;
static thread_local JNIEnv* env;
void init() {
java_util_ArrayList = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList")));
java_util_ArrayList_ = env->GetMethodID(java_util_ArrayList, "<init>", "(I)V");
java_util_ArrayList_size = env->GetMethodID (java_util_ArrayList, "size", "()I");
java_util_ArrayList_get = env->GetMethodID(java_util_ArrayList, "get", "(I)Ljava/lang/Object;");
java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)Z");
}
std::vector<std::string> java2cpp(jobject arrayList) {
jint len = env->CallIntMethod(arrayList, java_util_ArrayList_size);
std::vector<std::string> result;
result.reserve(len);
for (jint i=0; i<len; i++) {
jstring element = static_cast<jstring>(env->CallObjectMethod(arrayList, java_util_ArrayList_get, i));
const char* pchars = env->GetStringUTFChars(element, nullptr);
result.emplace_back(pchars);
env->ReleaseStringUTFChars(element, pchars);
env->DeleteLocalRef(element);
}
}
Push ArrayList from JNI back to Java
将 ArrayList 从 JNI 推送回 Java
If you don't modify this list in JNI, then the best strategy would be to simply keep a global reference to it somewhere in your native code. If you modify it a little, keep this jobjectalways up-to-date (you will probably need the methods java_util_ArrayList_addor java_util_ArrayList_set).
如果您不在 JNI 中修改此列表,那么最好的策略是在您的本机代码中的某处简单地保留对它的全局引用。如果你修改了一点,保持这个jobject始终保持最新(你可能会需要的方法java_util_ArrayList_add或java_util_ArrayList_set)。
If you choose to reconstruct the list from scratchthe vector, you will unwind the above method:
如果您选择从头开始重建向量列表,您将展开上述方法:
jobject cpp2java(std::vector<std::string> vector) {
jobject result = env->NewObject(java_util_ArrayList, java_util_ArrayList_, vector.size());
for (std::string s: vector) {
jstring element = env->NewStringUTF(s.c_str());
env->CallBooleanMethod(result, java_util_ArrayList_add, element);
env->DeleteLocalRef(element);
}
return result;
}
At any rate, be careful with threads when you work with Jni, always attach your native threads and detach before the native thread is destroyed.
无论如何,在使用 Jni 时要小心线程,始终附加本地线程并在本地线程被销毁之前分离。