NDK基本資料型別及操作
1.資料型別
2.引用型別
3.資料和物件型別的基本操作
(1)string型別,在native中並不提供修改string型別函式,因為java中也是步伐修改存在的string的型別即string型別在java中不變型別的
jstring javaString;
javaString = (*env)->NewStringUTF(env, "Hello World!");
逆過程
const jbyte* str; jboolean isCopy; str = (*env)->GetStringUTFChars(env, javaString, &isCopy);
即讓是物件(引用型別),我們就要去釋放他的引用,這個細節是java程式設計師比較容易忘記的
(*env)->ReleaseStringUTFChars(env, javaString, str);
(2)資料型別
通過New<Type>Array類建立
type範圍:Int,
Char,
Boolean, etc
jintArray javaArray;
javaArray = (*env)->NewIntArray(env, 10);
if (0 != javaArray) {
/* You can now use the array. */
}
接著就是操作資料中的元素
從java中拷貝
jint nativeArray[10];
(*env)->GetIntArrayRegion(env, javaArray, 0, 10, nativeArray);
逆過程
(*env)->SetIntArrayRegion(env, javaArray, 0, 10, nativeArray);
或者直接全部拷貝
<span style="font-family:TheSansMonoConNormal;color:#000000;FONT-VARIANT: normal; FONT-STYLE: normal; FONT-SIZE: 9pt">jint* nativeDirectArray; <span style="font-family:TheSansMonoConNormal;color:#000000;FONT-VARIANT: normal; FONT-STYLE: normal; FONT-SIZE: 9pt">jboolean isCopy;</span> </span>
nativeDirectArray = (*env)->GetIntArrayElements(env, javaArray, &isCopy);
別忘記釋放
Release<Type>ArrayElemens
例如
(*env)->ReleaseIntArrayElements(env, javaArray, nativeDirectArray, 0);
記得資料的內容可能被我們已經修改了,所以追後的一個引數告訴系統如何處理
(3).位元組型別
位元組型別是比較重要而且是需要注意的,因為位元組沒有大小,他需要你指定大小,在java中之所以string為不變型別就是這個原因吧,因為string儲存必須指定記憶體大小
所以我們動態申請
unsigned char* buffer = (unsigned char*) malloc(1024);
...
jobject directBuffer;
directBuffer = (*env)->NewDirectByteBuffer(env, buffer, 1024);
我們直接申請了1024個位元組來的buffer來構建jobject
接著我們也可以獲取
unsigned char* buffer;
buffer = (unsigned char*) (*env)->GetDirectBufferAddress(env,
directBuffer);
記得free申請的記憶體
4.獲取java class的屬性
(1)獲取class
jclass clazz;
clazz = (*env)->GetObjectClass(env, instance);
instance對應java的型別
(2)獲取欄位
jfieldID instanceFieldId;
instanceFieldId = (*env)->GetFieldID(env, clazz,"instanceField", "Ljava/lang/String;");
特殊的---靜態型別
jfieldID staticFieldId;
staticFieldId = (*env)->GetStaticFieldID(env, clazz,"staticField", "Ljava/lang/String;");
對於物件GetStatic<Type>Field
jstring staticField;
staticField = (*env)->GetStaticObjectField(env, clazz, staticFieldId);
5.呼叫方法
呼叫方法有兩種
思路 找到方法的ID,再call方法
(1)呼叫例項方法
instanceMethodId = (*env)->GetMethodID(env, clazz,"instanceMethod", "()Ljava/lang/String;");
(2)呼叫靜態方法
staticMethodId = (*env)->GetStaticMethodID(env, clazz,"staticMethod", "()Ljava/lang/String;");
接著呼叫方法,方法會有返回型別,所以使用
(1)呼叫例項方法
Call<Type>Method
如:
jstring instanceMethodResult;
instanceMethodResult = (*env)->CallStringMethod(env,instance, instanceMethodId);
(2)呼叫靜態方法
CallStatic<Type>Field
6.屬性或型別的簽名
如上我們
jstring staticField;
staticField = (*env)->GetStaticObjectField(env, clazz, staticFieldId);
其中staticFieldId是指定java中的型別的,這樣系統才知道我們從java中拿了什麼樣的資料
就像
staticMethodId = (*env)->GetStaticMethodID(env, clazz,"staticMethod", "()Ljava/lang/String;");
告訴系統返回String
其實說了這麼多,你只要明白,對於屬性型別,他就要有個可以形容這個是什麼型別屬性的描述,而方法就用簽名描述,我們可以使用javap
看看我們java物件的屬性和方法的簽名