現在我們知道了怎樣使用native code訪問簡單的數據類型和引用參考類型(string,array),下面我們來介紹怎樣讓jni代碼去訪問java中的成員變量和成員函數,然后可以再jni中回調java中的方法。
-------------------------------------------------------------------------------------
Accessing fields
java提供2中成員,靜態成員和非靜態成員,JNI支持了怎么樣去get和set這些靜態以及非靜態成員的方法,下面來舉一個例子。
先來訪問非靜態成員。
我們先在類中聲明一個非靜態的成員變量:
?
[java]? view plain copy
public?class?MyJNI?extends?Activity?{??????????????????private?String?s="123";??
在點擊按鈕的時候我們把title的textview的字符串改成s,
?
?
[java]? view plain copy
MyJNI?mj?=?new?MyJNI();?? ?? mj.accessField();?? tv.setText(mj.s);??
java代碼很簡單,只要實現我們的功能就好了,下面來看jni是如何進入class中的成員變量的:
?
?
[cpp]? view plain copy
Java_com_android_jni_MyJNI_accessField(JNIEnv?*env,jobject?obj)?? {?? ????jfieldID?fid;?? ????jstring?jstr;?? ????const?char?*str;?? ?? ?????? ????jclass?cls?=?(*env)->GetObjectClass(env,obj);?? ?? ????__android_log_print(ANDROID_LOG_INFO,"-JNI-","here?in?native?C!");?? ?????? ????fid?=?(*env)->GetFieldID(env,cls,"s",?? ????????????"Ljava/lang/String;");?? ????if(fid?==?NULL){?? ????????__android_log_print(ANDROID_LOG_INFO,"-JNI-","can?not?find?field");?? ????????return;?? ????}?? ?????? ????jstr?=?(*env)->GetObjectField(env,obj,fid);?? ????str?=?(*env)->GetStringUTFChars(env,jstr,NULL);?? ????if(str?==?NULL)?? ????????return;?? ????(*env)->ReleaseStringUTFChars(env,jstr,str);?? ?????? ????jstr?=?(*env)->NewStringUTF(env,"abc");?? ????if(jstr?==?NULL)?? ????????return;??? ????(*env)->SetObjectField(env,obj,fid,jstr);?? }??
為了訪問目標類中的成員變量,要做2步,首先呼叫GetFieldID從類中來得到一個field ID,根據成員的名字和描述:
?
fid = (*env)->GetFieldID(env,cls,"s",
"Ljava/lang/String;");
然后根據這個field ID來訪問這個成員:
jstr = (*env)->GetObjectField(env,obj,fid);
因為在java中string是對象,所以這邊呼叫的是GetObjectField函數。
最后運行模擬器,點擊按鈕的時候textView會變成JNI中修改的“abc”
ok,這部分結束,下面來看如何訪問靜態成員變量。
同樣的java代碼中:
?
[java]? view plain copy
public?class?MyJNI?extends?Activity?{?? ?????? ?????? ????private?static?int?si=100;?? ????private?String?s="123";?? ?
我們定義一個靜態的整形變量si初始化為100,當我們點擊按鈕的時候通過jni訪問static field來改變si的值,然后再title的textView中顯示出來。
?
[java]? view plain copy
MyJNI?mj?=?new?MyJNI();?? ?? mj.accessStaticField();?? tv.setText(mj.si+"");??
我們來看下如何進入static field:
?
?
[cpp]? view plain copy
void?? Java_com_android_jni_MyJNI_accessStaticField(JNIEnv?*env,jobject?obj)?? {?? ????jfieldID?fid;????? ????jint?si;?? ?? ?????? ????jclass?cls?=?(*env)->GetObjectClass(env,obj);?? ????__android_log_print(ANDROID_LOG_INFO,"-JNI-","here?in?native?C!");?? ?????? ?????? ????fid?=?(*env)->GetStaticFieldID(env,cls,"si","I");?? ????if(fid?==?NULL)?? ????????return;??? ?????? ????si?=?(*env)->GetStaticIntField(env,cls,fid);?? ????(*env)->SetStaticIntField(env,cls,fid,200);?? }??
大家可以看到只是調用的方法不一樣,多了一個static,和非靜態的使用方法一樣。
?
-------------------------------------------------------------------------------------------------------
jni中訪問class 中的field就到此結束,下面一篇會介紹如何訪問java中class 的method。
?
總結
以上是生活随笔為你收集整理的android jni ——Field Method -- Accessing Field的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。