Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android NDK學習筆記6-JNI對引用數據類型的操作

Android NDK學習筆記6-JNI對引用數據類型的操作

編輯:關於Android編程

字符串操作

JNI把Java字符串當成引用類型來處理,JNI提供了java字符串與C字符串之間相互轉換的必要函數。因為java字符串對象是不可變的,因此JNI不提供任何修改現有的java字符串內容的函數。
● 創建字符串
可以在原生代碼中用NewString函數構建Unicode編碼格式的字符串實例,用NewStringUTF函數構建UTF-8編碼格式的字符串實例。
例如:下面的函數以一個C字符串為參數,並返回一個Java字符串引用類型jstring值。

jstring javastring
javastring = (*env)->NewStringUTF(env, "I LOVE YOU UU!");

注意,在內存溢出的情況下,NewString函數將返回NULL以通知原生代碼虛擬機中有異常拋出。
● 把java字符串轉換成C字符串
為了在原生代碼中使用java字符串,需要先將java字符串轉換成C字符串,我們使用GetStringChars函數可以將Unicode格式的java字符串轉換成C字符串,使用GetStringUTFChars函數可以將UTF-8格式的Java字符串轉換成C字符串。這些函數的第三個參數均為可選參數,該可選參數名是isCopy,它讓調用者確定返回的C字符串地址指向副本還是指向堆中的固定對象。例如:

const jbyte* str;
jboolean isCopy;

str = (*env)->GetStringUTFChars(env, javaString,&isCopy);
if(0 != str){
    printf("java String: %s",str);
    if(JNI_TRUE == isCopy){
        printf("C String is a copy of the java String");
    }else{
        printf("C String points to actual String");
    }
}

● 釋放字符串
通過JNI GetStringChars 函數GetStringUTFChars函數獲得的C字符串在原生代碼中使用完成之後需要正確的釋放,否則將會引起內存洩漏。通常我們使用ReleaseStringChars函數釋放Unicode格式的字符串,使用ReleaseUTFStringChars函數釋放UTF-8格式的字符串.

(*env)->ReleaseUTFStringChars(env,javaString,str);

數組操作

JNI把java數組當成引用類型來處理,JNI提供必要的函數訪問和處理Java數組。
● 創建數組
用NewArray函數在原生代碼中創建數組實例,其中可以是Int、Char和Boolean等。例如:

jintArray javaArray;
javaArray = (*env)->NewIntArray(env,10);
if(0 != javaArray){
/*數組使用……*/
}

注意,在內存溢出的情況下,NewArray函數將返回NULL以通知原生代碼虛擬機中有異常拋出。
● 訪問數組元素
JNI提供兩種訪問java數組元素的方法,可以將數組的代碼賦值成C數組或者讓JNI提供直接執行數組元素的指針。
● 對副本的操作
GetArrayRegion函數將給定的基本Java數組賦值到給對你給的C數組中,例如:

jint nativeArray[10];
(*evn)->GetIntArrayRegion(env,javaArray,0,10,nativeArray);

原生代碼可以像使用普通的C數組一樣使用和修改數組元素。當原生代碼想將所做的修改提交給java數組時,可以使用SetArrayRegion函數將C數組復制回java數組中。例如:

(*env)->SetIntArrayRegion(env,javaArray,0,10,nativeArray);

注意:當數組很大時,對數組做復制操作會引起性能問題。
● 對直接指針的操作
原生代碼可以使用GetArrayElements函數獲取執行數組元素的直接指針。例如:

jint nativeDirectArray;
jboolean isCopy;

nativeDirectArray = (*env)->GetIntArrayElements(env,javaArray,&isCopy);

其中,第三個&isCopy參數為可選參數,讓調用者確定返回的C字符串地址指向副本還是指向堆中的固定對象。
因為可以像普通的C數組一樣訪問和處理數組元素,因此JNI沒提供訪問和處理數組元素的方法,JNI要求原生代碼用完這些指針後立刻釋放,否則會出現內存溢出。可以使用JNI提供的ReleaseArrayElements函數釋放GetArrayElements返回的C數組。例如:

(*env)->ReleaseIntArrayRegion(env,javaArray,nativeDirectArray,0);

其中第四個參數是釋放模式。
釋放模式動作0將內容復制回來並釋放原生數組JNI_COMMIT將內容復制回來但是不釋放原生數組,一般用於周期性的更新一個java數組JNI_ABORT釋放原生數組但不用將內容復制回來

這裡寫圖片描述

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved