最近要调整一个工程,里面有用到JNI,做个笔记,环境为:Windows7+eclipse。
参考贴:
http://blog.csdn.net/shulianghan/article/details/18964835
过程:
1.down一个最简单的用到了JNI的工程
https://github.com/han1202012/NDKHelloworld.git
2.在上面的工程里加个批处理文件
常见问题:
1.include <string>缺提示找不到
解决办法:
http://stackoverflow.com/questions/10373788/c-unresolved-inclusion-iostream
2.从公司服务器down了一个工程,右键properties里有c++相关的部分,但是从网上down了一个工程,却看不到CDT插件的影子?这是为什么呢?
后来从公司的工程里拷贝了一个.project文件过来,就有了!细想一下,好像我电脑确实没装过CDT插件,估计这个.project文件里有什么东西。
3.程序莫名闪退,找了好久原因才发现,java代码中声明一个函数
native public static boolean sendMessageToOneMobile(String mobile,String msg);
c++中定义函数的时候,这前两个参数(JNIEnv *env,jobject thiz)一定要带上
因为调用的时候,实参是会传过去的!!!
JNIEXPORT bool JNICALL Java_shuliang_han_ndkhelloworld_MainActivity_sendMessageToOneMobile
(JNIEnv *env,jobject thiz,jstring mobile,jstring msg ){}
4.native读取java传递过来的String[],存储为char**
参考贴:
http://liuxp0827.blog.51cto.com/5013343/1378277
JNIEXPORT void JNICALL Java_shuliang_han_ndkhelloworld_MainActivity_nativeSendMessageToMobiles(
JNIEnv *env,jobject thiz,jobjectArray mobiles,jstring msg ){
jstring jstr;
jsize arraysize = env->GetArrayLength(mobiles);
const char **pstr = (const char **) malloc(arraysize*sizeof(char *));
for (int i=0 ; i<arraysize; i++) {
jstr = (jstring)env->GetObjectArrayElement(mobiles, i);
pstr[i] = (char *)env->GetStringUTFChars(jstr, 0);
}
const char *nativemsg = env->GetStringUTFChars(msg, 0);
DataTransDemo::sendMessageToMobiles(pstr,arraysize,nativemsg);
env->ReleaseStringUTFChars(msg,nativemsg);
for(int i=0;i<arraysize;i++){
jstr = (jstring)env->GetObjectArrayElement(mobiles, i);
env->ReleaseStringUTFChars(jstr,pstr[i]);
env->DeleteLocalRef(jstr);
}
free(pstr);
}
5.native将char**装换成String[]传递给java
参考贴:
https://coderanch.com/t/326467/java/Returning-String-array-program-Java
http://zhiweiofli.iteye.com/blog/1830319
bool DataTransDemo::sendMessageToMobiles(const char* mobiles[],const char* msg){
SGJniMethodInfo t;
bool bRlt = true;
if (SGSDKJniHelper::getStaticMethodInfo(t, CLASS_NAME, "sendMessageToMobiles","([Ljava/lang/Object;Ljava/lang/String;)Z")) {
SGLOGD("DataTransDemo::sendMessageToMobiles begin");
jstring strMessage = t.env->NewStringUTF(msg);
jobjectArray mobilearray;
mobilearray= (jobjectArray)t.env->NewObjectArray(size,t.env->FindClass("java/lang/String"),NULL);
for(int i=0;i<size;i++){
jstring mobilestring = t.env->NewStringUTF(mobiles[i]);
t.env->SetObjectArrayElement(mobilearray,i,mobilestring);
t.env->DeleteLocalRef(mobilestring);
}
bRlt = t.env->CallStaticBooleanMethod(t.classID, t.methodID, mobilearray, strMessage);
t.env->DeleteLocalRef(t.classID);
t.env->DeleteLocalRef(strMessage);
t.env->DeleteLocalRef(mobilearray);
SGLOGD("DataTransDemo::sendMessageToMobiles ok");
}else{
SGLOGD("DataTransDemo::sendMessageToMobiles getStaticMethodInfo error");
bRlt = false;
}
return bRlt;
}
6.关于jni里释放资源