将字符串的arraylist从Native java返回到JNI

时间:2015-10-29 05:26:28

标签: java arraylist java-native-interface native

           ArrayList<String> myArraylist;          

           public ArrayList<String> getData(){
               myArraylist = new ArrayList<String>();          
               myArraylist.add("1267982563");
               myArraylist.add("2345678");
               myArraylist.add("5432789");
               return myArraylist;
           }

如何从JNI端的上述方法中获取每个项目,并推送到向量并从JNI返回到JNI层中的其他CPP调用。

1 个答案:

答案 0 :(得分:15)

将ArrayList转换为std :: vector&lt; std :: string&gt;:

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);
  }
}

将ArrayList从JNI推送回Java

如果你不在JNI中修改这个列表,那么最好的策略就是在你的本机代码中的某个地方保持对它的全局引用。如果您稍微修改它,请保持此 jobject 始终保持最新(您可能需要方法 java_util_ArrayList_add java_util_ArrayList_set )。< / p>

如果您选择从 scratch 向量重建列表,您将展开上述方法:

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;
}

无论如何,在使用Jni时要小心线程,在本机线程被销毁之前,请始终附加本机线程并分离。