最近项目中有部分需求需要给Android端实现部分功能,以jni方式实现,对此方式不是很熟悉,浅浅地记录一下 当参数类型为HashMap<Integer, ArrayList>时,该如何在C++中向此容器插入数据的问题.
代码片段如下
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_myProject_XXNative_myFun(JNIEnv *env, jclass clazz, jobject desMap)
{
//...
std::map<int, std::vector<myStruct>> srcMap;
std::map<int, std::vector<myStruct>>::iterator iter = srcMap.begin();
for(; iter != srcMap.end(); iter++)
{
int nKey = iter->first;
jclass integerClass = env->FindClass("java/lang/Integer");
jmethodID integerConstructorID = env->GetMethodID(integerClass, "<init>", "(I)V");
jobject key = env->NewObject(integerClass, integerConstructorID, nKey);
std::vector<myStruct> srcVec = iter->second;
int nSize = srcVec.size();
jclass mapClass = env->FindClass("java/util/HashMap");
jmethodID putMethodID =
env->GetMethodID(
mapClass,
"put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;" );
jclass arrayListClass = env->FindClass("java/util/ArrayList");
jmethodID arrayListInit = env->GetMethodID(arrayListClass, "<init>", "()V");
jmethodID addToList = env->GetMethodID(
arrayListClass,
"add",
"(Ljava/lang/Object;)Z" );
jobject listObj = env->NewObject(arrayListClass, arrayListInit);
for(int i = 0; i < nPaperSize; i++)
{
myStruct tObj = srcVec.at(i);
jstring firstStr = str2jstring(env, tObj.firstStr.c_str());
jstring secondStr = str2jstring(env, tObj.secondStr.c_str());
env->CallBooleanMethod(listObj, addToList, firstStr);
env->CallBooleanMethod(listObj, addToList, secondStr);
env->DeleteLocalRef(firstStr);
env->DeleteLocalRef(secondStr);
}
env->CallObjectMethod(papers_map, putMethodID, key, listObj);
//资源释放
env->DeleteLocalRef(integerClass);
env->DeleteLocalRef(key);
env->DeleteLocalRef(mapClass);
env->DeleteLocalRef(arrayListClass);
env->DeleteLocalRef(listObj);
}
}
顺便一提,如果参数中想以引用传递方式传java中的String类型(传到C++方法中修改赋值),可以用StringBuffer实现
代码片段如下
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_myProject_XXNative_myFun(JNIEnv *env, jclass clazz, jobject str_id)
{
std::string strId;
jstring jstrId = env->NewStringUTF(strId.c_str());
jclass stringBufferClass = env->FindClass("java/lang/StringBuffer");
jmethodID appendMethodID =
env->GetMethodID(
stringBufferClass,
"append",
"(Ljava/lang/Object;)Ljava/lang/StringBuffer;" );
env->CallObjectMethod(str_id, appendMethodID, jstrId);
//资源释放
env->DeleteLocalRef(jstrId);
env->DeleteLocalRef(stringBufferClass);
}