NDK開發之訪問域
Java有兩類域,實例域和靜態域。類的每個實例都有自己的實例域副本,而一個類的所有實例共享一個靜態域(Java SE基礎)。
JNI提供了相應的函數來訪問這兩類域,總體步驟是這樣的:
1.通過對象引用獲得類
2.通過類獲得域ID
3.通過域ID獲取域
下面我們按步驟一步一步來:
我們的Java類中有兩個域,一個靜態域,一個實例域:
private static String staticFiled = "a static Filed465"; private String instanceFiled = "a instance Filed123";
1
2
訪問該域的三個步驟:
1通過對象引用獲得類
jclass clazz; //定義域ID jfieldID instanceFieldId; jfieldID staticFieldId; //定義域 jstring instanceFieldStr; jstring staticFieldStr; //通過對象引用獲得類 clazz = (*env)->GetObjectClass(env, thiz);
1
2
3
4
5
6
7
8
9
2通過類獲得域ID
//通過類獲得域ID instanceFieldId = (*env)->GetFieldID(env,clazz,"instanceFiled","Ljava/lang/String;"); staticFieldId = (*env)->GetStaticFieldID(env,clazz,"staticFiled","Ljava/lang/String;");
1
2
3
這里兩個函數的最后一個參數是Java中表示域類型的域描述符,"Ljava/lang/String;"表明域類型是String。
一般情況下,為了提高應用程序的性能,我們可以緩存域ID,一般總是緩存使用最頻繁的域ID
3.通過域ID獲取域
//通過域ID獲得域 instanceFieldStr = (*env)->GetObjectField(env,thiz,instanceFieldId); staticFieldStr = (*env)->GetStaticObjectField(env,clazz,staticFieldId);
1
2
3
為了證明我們已經成功獲得域,我們把jstring轉為c字符串之后然后打印出來(打印日志請看NDK開發之日志打印):
const jbyte* str1; const jbyte* str2; str1 = (*env)->GetStringUTFChars(env,instanceFieldStr,0); str2 = (*env)->GetStringUTFChars(env,staticFieldStr,0); LOGI("the string is :%s",str1); LOGI("the string is :%s",str2);
1
2
3
4
5
6
打印結果:
完整的程序是這樣的:
void Java_com_example_jni_MainActivity_updateField(JNIEnv* env, jobject thiz) { jclass clazz; //定義域ID jfieldID instanceFieldId; jfieldID staticFieldId; //定義域 jstring instanceFieldStr; jstring staticFieldStr; //通過對象引用獲得類 clazz = (*env)->GetObjectClass(env, thiz); //通過類獲得域ID instanceFieldId = (*env)->GetFieldID(env,clazz,"instanceFiled","Ljava/lang/String;"); staticFieldId = (*env)->GetStaticFieldID(env,clazz,"staticFiled","Ljava/lang/String;"); //通過域ID獲得域 instanceFieldStr = (*env)->GetObjectField(env,thiz,instanceFieldId); staticFieldStr = (*env)->GetStaticObjectField(env,clazz,staticFieldId); //jstring轉為C字符串然后打印出來 const jbyte* str1; const jbyte* str2; str1 = (*env)->GetStringUTFChars(env,instanceFieldStr,0); str2 = (*env)->GetStringUTFChars(env,staticFieldStr,0); LOGI("the string is :%s",str1); LOGI("the string is :%s",str2); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
總結
大家都看到了,獲得單個域需要三個步驟,這真是太麻煩了,經常這樣搞會影響程序的性能,因此建議如果在原生方法中需要 使用域,這些域最好作為參數傳遞給原生方法,而不要讓原生代碼回到Java中。
Java
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。