標籤:
最近一直在學安卓的jni,主要參考的是黑馬程式員的視頻教程,講的確實不錯。
那就自己總結一下吧,算是對學習的複習。
這篇部落格也主要參考了這位博主:http://www.cnblogs.com/activity-life/p/3643047.html,在這裡謝謝了
通過他的部落格和視頻教程,我結合了兩者的方法,把功能實現了,畢竟這個是應用為主,自己學藝不精,這裡積累下:
第一篇部落格的總結所有Java調取jni是關於字串的操作,主要包括以下三種類型:
//對基礎資料型別 (Elementary Data Type)字串的訪問 //0.無輸入,有輸出為字串 public native String helloFromC(); //1.有輸入,有輸出訪問字串 private native String GetNativeString(String str); //2.輸入字串,並附帶長度,輸出字串 public native String encode(String text,int length); public native String decode(String text,int length);
那麼根據教程所講,當有輸入字串作為參數傳過來時,使用如下函數將其轉換為C語言的字串函數指標:
//把java的字串轉換成c的字串char* Jstring2CStr(JNIEnv* env, jstring jstr){ char* rtn = NULL; jclass clsstring = (*env)->FindClass(env,"java/lang/String"); jstring strencode = (*env)->NewStringUTF(env,"GB2312"); jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312"); jsize alen = (*env)->GetArrayLength(env,barr); jbyte* ba = (*env)->GetByteArrayElements(env,barr,JNI_FALSE); if(alen > 0) { rtn = (char*)malloc(alen+1); //"\0" memcpy(rtn,ba,alen); rtn[alen]=0; } (*env)->ReleaseByteArrayElements(env,barr,ba,0); // return rtn;}
之後對其操作,這裡我將對以上三種類型分別展示jni中的使用:
0.無輸入,有輸出為字串:
jstring Java_com_swust_string_MainActivity_helloFromC(JNIEnv* env,jobject obj){ //C語言的字串 char* cstr="hello paopao from C"; //把C語言字串轉換為Java的字串 //jstring (*NewStringUTF)(JNIEnv*, const char*); //jstring jstr=(*(*env)).NewStringUTF(env,cstr) jstring jstr = (*env)->NewStringUTF(env, cstr); return jstr;}
1.有輸入,有輸出訪問字串:
//把java的字串轉換成c的字串char* Jstring2CStr(JNIEnv* env, jstring jstr){ char* rtn = NULL; jclass clsstring = (*env)->FindClass(env,"java/lang/String"); jstring strencode = (*env)->NewStringUTF(env,"GB2312"); jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312"); jsize alen = (*env)->GetArrayLength(env,barr); jbyte* ba = (*env)->GetByteArrayElements(env,barr,JNI_FALSE); if(alen > 0) { rtn = (char*)malloc(alen+1); //"\0" memcpy(rtn,ba,alen); rtn[alen]=0; } (*env)->ReleaseByteArrayElements(env,barr,ba,0); // return rtn;}JNIEXPORT jstring JNICALL Java_com_swust_string_MainActivity_GetNativeString (JNIEnv *env, jobject obj, jstring jstr){ //擷取輸入的字串 char* cstr=Jstring2CStr(env,jstr); char* pUTF8Str = "From jni String"; strcat(cstr, "/"); //加一個分隔字元 strcat(cstr, pUTF8Str); //聯結一個本地字串 //C語言的字串轉換為jstring return (*env)->NewStringUTF(env,cstr);}
自己實現的準系統是將Java傳入的字串和C的字串合并,並返回。
2.輸入字串,並附帶長度,輸出字串:
該種類型根據教程寫了兩個函數(編碼和解碼),可視為同一種類型:
//把java的字串轉換成c的字串char* Jstring2CStr(JNIEnv* env, jstring jstr){ char* rtn = NULL; jclass clsstring = (*env)->FindClass(env,"java/lang/String"); jstring strencode = (*env)->NewStringUTF(env,"GB2312"); jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312"); jsize alen = (*env)->GetArrayLength(env,barr); jbyte* ba = (*env)->GetByteArrayElements(env,barr,JNI_FALSE); if(alen > 0) { rtn = (char*)malloc(alen+1); //"\0" memcpy(rtn,ba,alen); rtn[alen]=0; } (*env)->ReleaseByteArrayElements(env,barr,ba,0); // return rtn;}JNIEXPORT jstring JNICALL Java_com_swust_string_MainActivity_GetNativeString (JNIEnv *env, jobject obj, jstring jstr){ //擷取輸入的字串 char* cstr=Jstring2CStr(env,jstr); char* pUTF8Str = "From jni String"; strcat(cstr, "/"); //加一個分隔字元 strcat(cstr, pUTF8Str); //聯結一個本地字串 //C語言的字串轉換為jstring return (*env)->NewStringUTF(env,cstr);}JNIEXPORT jstring JNICALL Java_com_swust_string_MainActivity_encode (JNIEnv *env, jobject obj, jstring jstr , jint length){ //根據老師給的函數,產生C語言的字元指標 //arg1:Java環境指標 arg2:java的字串 char* cstr=Jstring2CStr(env,jstr); int i=0; //C語言的int和jint的相同,故直接使用length for(i=0;i<length;i++){ *(cstr+i)+=1; } //C語言的字串轉換為jstring return (*env)->NewStringUTF(env,cstr);}
為了代碼看起來比較明了,這裡不貼項目代碼了,只展示:
0.無輸入,有輸出為字串:顯示“hello paopao from c"
1.有輸入,有輸出訪問字串:顯示”hello from java / hello from jni"
2.輸入字串,並附帶長度,輸出字串:顯示編碼和解碼功能:
Android jni 編程1(對基本類型字串的操作)