android jni ——Field & Method –> Accessing Field

現在我們知道瞭怎樣使用native code訪問簡單的數據類型和引用參考類型(string,array),下面我們來介紹怎樣讓jni代碼去訪問java中的成員變量和成員函數,然後可以再jni中回調java中的方法。

————————————————————————————-

Accessing fields

java提供2中成員,靜態成員和非靜態成員,JNI支持瞭怎麼樣去get和set這些靜態以及非靜態成員的方法,下面來舉一個例子。

先來訪問非靜態成員。

我們先在類中聲明一個非靜態的成員變量:

[java]
public class MyJNI extends Activity { 
    /** Called when the activity is first created. */ 
    //declear a instance field 
    private String s="123"; 

在點擊按鈕的時候我們把title的textview的字符串改成s,

[java]
MyJNI mj = new MyJNI(); 
 
mj.accessField(); 
tv.setText(mj.s); 

java代碼很簡單,隻要實現我們的功能就好瞭,下面來看jni是如何進入class中的成員變量的:

[cpp]
Java_com_android_jni_MyJNI_accessField(JNIEnv *env,jobject obj) 

    jfieldID fid; 
    jstring jstr; 
    const char *str; 
 
    //get a reference to obj's class 
    jclass cls = (*env)->GetObjectClass(env,obj); 
//  jclass cls = (*env)->FindClass(env,"com/android/jni/Native"); 
    __android_log_print(ANDROID_LOG_INFO,"-JNI-","here in native C!"); 
    //look for the instance field in cls 
    fid = (*env)->GetFieldID(env,cls,"s", 
            "Ljava/lang/String;"); 
    if(fid == NULL){ 
        __android_log_print(ANDROID_LOG_INFO,"-JNI-","can not find field"); 
        return; 
    } 
    //read the instance field s 
    jstr = (*env)->GetObjectField(env,obj,fid); 
    str = (*env)->GetStringUTFChars(env,jstr,NULL); 
    if(str == NULL) 
        return; 
    (*env)->ReleaseStringUTFChars(env,jstr,str); 
    //create a new string and overwrite the instance field 
    jstr = (*env)->NewStringUTF(env,"abc"); 
    if(jstr == NULL) 
        return; //out of memory 
    (*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]
public class MyJNI extends Activity { 
    /** Called when the activity is first created. */ 
    //declear a instance field 
    private static int si=100; 
    private String s="123"; 

 

 

我們定義一個靜態的整形變量si初始化為100,當我們點擊按鈕的時候通過jni訪問static field來改變si的值,然後再title的textView中顯示出來。

[java]
MyJNI mj = new MyJNI(); 
 
mj.accessStaticField(); 
tv.setText(mj.si+""); 

我們來看下如何進入static field:

[cpp] 
Java_com_android_jni_MyJNI_accessStaticField(JNIEnv *env,jobject obj) 

    jfieldID fid;   //store the field id 
    jint si; 
 
    //get a reference to obj's class 
    jclass cls = (*env)->GetObjectClass(env,obj); 
    __android_log_print(ANDROID_LOG_INFO,"-JNI-","here in native C!"); 
     
    //look for the static field si in lcs 
    fid = (*env)->GetStaticFieldID(env,cls,"si","I"); 
    if(fid == NULL) 
        return; //field not found 
    //access the static field si 
    si = (*env)->GetStaticIntField(env,cls,fid); 
    (*env)->SetStaticIntField(env,cls,fid,200); 

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *