首頁 > 手機軟體

android ndk jni 字串 String jstring

2019-11-27 20:19:22

       在android ndk開發的過程中,經常會遇到字串的問題,但是 jstring 這個型別又不同於一般的陣列,那麼String的具體的操作該怎麼進行了?程式碼主要涉及:

        ① UTF編碼轉換(一般情況下夠用,由於系統提供介面,所以比較簡單);

        ② 其他編碼格式轉換;

        方便他人亦是方便自己,如果覺得還行就點下右邊投票吧,這樣可以幫助其他人更快的找到解決問題的方法;有疑問的也可留言哦, 謝謝!

       

1

UTF由於有系統提供了介面實現起來非常的簡單,主要涉及四個介面,如下圖所示:


2

jstring?轉?uft?字元集:?GetStringUTFLength?可以獲取該jstring的長度,如:uftLength = env->GetStringUTFLength(jstring);註:?Java裡面的String並不是按照結束,並作為結束符,所以必須返回字串的長度GetStringUTFChars?可以獲取對應的轉換後的內容,該函數的最後一個jboolean型別的引數傳0就可以了,如:char* pcUtf = env->GetStringUTFChars(jstring, 0);ReleaseStringUTFChars?該函數負責釋放GetStringUTFChars?返回的指標,如:
env->ReleaseStringUTFChars(jstring, pcUtf);

3

utf?字元集轉?jstring:NewStringUTF?通過這個函數一個就可以直接實現?utf?字元集轉?jstring,如:env->NewStringUTF?(uft);

1

獲取String類的方法的函數簽名:

① 系統的原始碼目錄,找android.jar

如我的是:"D:Androidadt-bundle-windows-x86_64-20140702sdkplatformsandroid-19android.jar"

② 解壓 android.jar 到目錄 android 裡面

③ 開啟cmd,cd到該目錄

如我的是「D:Androidadt-bundle-windows-x86_64-20140702sdkplatformsandroid-19」

④ 執行cmd指令:javap -classpath android -s java.lang.String


2

查詢的結果如下圖所示:

  public byte[] getBytes(java.lang.String) throws java.io.UnsupportedEncodingException;   

descriptor: (Ljava/lang/String;)[B


3

android上面支援的字元集有,如下圖所示:

註:該字元集必須以android原始碼中的註釋為主,不同的平台支援的字元集可能不相同;


4

String類建構函式的簽名:

 public java.lang.String(byte[], java.lang.String) throws java.io.UnsupportedEncodingException;   descriptor: ([BLjava/lang/String;)V


1

下面的這個函數是實現了 jstring 到 char 的轉換;

pEnv 為當前的環境變數;

ppChars 為從jstring中獲取到的最終的char陣列,記憶體由函數內部開闢;

pLength 為jstring的長度;

jstr 為需要轉換的jstring型別;

szCharset 這裡傳字元集,「前期準備」部分有介紹

註:① Java裡面的String並不是按照結束,並作為結束符,所以必須返回字串的長度

② 該測試用例並沒有做例外處理,使用者可以自行補充上;

完整程式碼如下:

int jstring2char(JNIEnv* pEnv, char** ppChars, int* pLength, jstring jstr, char* szCharset)

{ jclass clsString = pEnv->FindClass("java/lang/String"); jstring charset = pEnv->NewStringUTF(szCharset); jmethodID method = pEnv->GetMethodID(clsString, "getBytes", "(Ljava/lang/String;)[B");

 jbyteArray byteArray = (jbyteArray) pEnv->CallObjectMethod(jstr, method, charset);

 jsize nLength = pEnv->GetArrayLength(byteArray);

 jbyte* bytes = pEnv->GetByteArrayElements(byteArray, JNI_FALSE);

 *pLength = nLength;  *ppChars = (char*) malloc(nLength);  memcpy(*ppChars, bytes, nLength);

 pEnv->ReleaseByteArrayElements(byteArray, bytes, 0); pEnv->DeleteLocalRef(charset);

 return 1;}


2

下面的這個函數是實現了 char 到 jstring 的轉換;

完整的程式碼如下:

jstring char2jstring(JNIEnv* pEnv, char* pChars, int Length, char* szCharset) {

 jclass clsString = pEnv->FindClass("java/lang/String");

 /// <init>屬於建構函式的範疇

 jmethodID construct = pEnv->GetMethodID(clsString, "<init>", "([BLjava/lang/String;)V");

 jbyteArray byteArray = pEnv->NewByteArray(Length);

 pEnv->SetByteArrayRegion(byteArray, 0, Length, (jbyte*) pChars);

 jstring charset = pEnv->NewStringUTF(szCharset);

 jstring strDst = (jstring) pEnv->NewObject(clsString, construct, byteArray, charset);

 pEnv->DeleteLocalRef(byteArray);

 return strDst;}


3

下面是一個完整的測試用例,將java層傳進來的 jstring 複製一份後重新傳回去,完整的程式碼如下:

JNIEXPORT jstring JNICALL Java_ndk_jniarray_MainActivity_swapString (JNIEnv *pEnv, jclass clsActivity, jstring src) {

    char* pUtf = NULL;

    int  nLength = 0;

    jstring2char(pEnv, &pUtf, &nLength, src, "UTF-8");  

    jstring dst = char2jstring(pEnv, pUtf, nLength, "UTF-8");

    free(pUtf);

    return dst;

}


4

       方便他人亦是方便自己,如果覺得還行就點下下邊投票吧,這樣可以幫助其他人更快的找到解決問題的方法;有疑問的也可留言哦, 謝謝!



IT145.com E-mail:sddin#qq.com