使用NDK移植开源项目,JNI的使用技巧

Jni 的介绍

JNI是Java Native Interface的缩写,免备案空间,中文为JAVA本地调用。从Java1.1开始,香港虚拟主机,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。以下介绍Android 中如何使用jni移植开源库的技巧.

JNI日志输出到Logcat中#include <android/log.h>#define LOG_TAG "===xcloud==="#define LOGI(…)android_log_print(ANDROID_LOG_INFO,LOG_TAG,VA_ARGS__)#define LOGW(…)android_log_print(ANDROID_LOG_WARN,LOG_TAG,VA_ARGS__)#define LOGE(…)android_log_print(ANDROID_LOG_ERROR,LOG_TAG,VA_ARGS__)

Android.mk文件添加编译模块:LOCAL_LDLIBS=-lm -llog使用方法:LOGE("%s",test);

JNI调用Java方法以调用String 的getBytes方法为例:第一步:jclass clsstring = (*env)->FindClass(env,"java/lang/String"); //找到Java String 类第二步:jstring strencode = (*env)->NewStringUTF(env,"utf-8");  //得到一个jstring 对象第三步:jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B"); //得到getBytes方法

第四步:jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env,jstr, mid, strencode); //“jstr 为传入的字符串”调用getBytes方法

第五步:jsize alen = (*env)->GetArrayLength(env,barr); //得到数组长度

jstring 转换 char*char* test=(char*)(*env)->GetStringUTFChars(env,jstringVariable,NULL);

返回一个java对象数组第一步:jclass objectClass=(*env)->FindClass(env,"com/xuzhitech/xcloud/resource"); //找到对应的java 类(对象)第二步:jobjectArray array=(*env)->NewObjectArray(env,currentListCount,objectClass,NULL); //通过取到的java类(对象)创建一个指定固定大小的数组第三步:jfieldID _uri=(*env)->GetFieldID(env,objectClass,"uri","Ljava/lang/String;");//找到对象中的列注意:在JNI中并未提供jstring 类型的对象,所以必须通过L指定包名找到该类,在有提供的类型中,可以直接使用该类型的大写首字母(jlong 需使用J)如jint 类型可以如此编写:jfieldID _vcr=(*env)->GetFieldID(env,objectClass,"is_vcr","I");对应的JNI提供类型可以参考如下 第四步:jmethodID jid = (*env)->GetMethodID(env,objectClass,"<init>","()V");//"<init>"代表可以访问默认构造函数jobject jobj=(*env)->NewObject(env,objectClass,jid); //通过第一步找到的jclass创建对应的对象

第五步:(*env)->SetObjectField(env,jobj,_modtime,jmodtime); //为对象中的每一列赋值。注意:如果JNI有提供的数据类型,可按提供的类型为对象中的列赋值,如:(*env)->SetIntField(env,jobj,_vcr,current->is_vcr);第六步:(*env)->SetObjectArrayElement(env,array,i,jobj);将对象设置进第二步声明的数组中DeleteLocalRef(env,jobj);//删除引用对象

在JNI中循环读取对象数组

for(i=0;i<currentListCount;i++){jobjectobj=(*env)->GetObjectArrayElement(env,array,i);jstringjstr=(*env)->GetObjectField(env,obj,_uri);LOGE(,jstringtoChar(env,jstr));}上面使用到的jstringtoChar方法代码:/***jstringtochar*/char*jstringtoChar(JNIEnv*env,jstringjstr){char*rtn=NULL;jclassclsstring=(*env)->FindClass(env,);jstringstrencode=(*env)->NewStringUTF(env,);jmethodIDmid=(*env)->GetMethodID(env,clsstring,,);jbyteArraybarr=(jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode);jsizealen=(*env)->GetArrayLength(env,barr);jbyte*ba=(*env)->GetByteArrayElements(env,barr,JNI_FALSE);if(alen>0){rtn=(char*)malloc(alen+1);memcpy(rtn,ba,alen);rtn[alen]=0;}(*env)->ReleaseByteArrayElements(env,barr,ba,0);returnrtn;

复制代码

}

cpp JNI与 c JNI的主要注意事项:用C编写jni文件,访问JNI内置提供方法格式:(*env)->SetObjectArrayElement(env,array,i,jobj);用CPP编写JNI文件,访问JNI内置提供方法格式:env->SetObjectArrayElement(array,i,jobj);另外,使用CPP编写的JNI代码,在调用C语言编写的库的时候,要添加以下代码,才可以正常使用(不然在链接的时候找不到相关接口:undefined reference…..):ifdef __cplusplusextern "C" {#endif… //引入的头文件#ifdef __cplusplus}#endif

其他用法几乎一致。

也有伤心的,既有令人兴奋的,也有令人灰心的,

使用NDK移植开源项目,JNI的使用技巧

相关文章:

你感兴趣的文章:

标签云: