JNI基礎(chǔ)(7): JNI訪問和修改Java類

7.1 java中的基本類型和引用類型的簽名規(guī)則
  • jni中 java類的簽名為: L + 包名 + 類名,再將原來的.改為/分隔符即可性昭。
    例如:java中的java.lang.String的簽名為Ljava/lang/String;拦止。

  • java中的基本類型的簽名為:

Field Descriptor Java Language Type
Z boolean
B byte
C char
S short
I int
J long
F float
D double
V void
Object L用/分割的包名
  • java 中的數(shù)組的簽名為:左中括號(hào)+對(duì)象或者基本類型的簽名即可糜颠;
Field Descriptor Java Language Type
object[] [Ljava/lang/Object;
int[] [I
float[] [F
7.2 JNI中訪問訪問java對(duì)象的字段并修改

JNI中修改任何java對(duì)象的字段值一般分為如下三步:

  • 先找到類
  • 找到類的字段id
  • 通過字段id獲取或者更新對(duì)象的該字段

如果類實(shí)例中還存在別的類的實(shí)例 也是按上面的邏輯分析一層層解剖就行

例如:
定義一個(gè)叫Person的java類和House的java類:

public class House {
    public int size = 100;
    public String location = "Beijing";
}

public class Person {

    protected String name;
    protected int age;
    protected House house;
    public static int num = 0;

    public Person(String name)
    {
        this.name = name;
        this.house = new House();
    }
    public String getName() {
        return name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    public static int getNum() {
        return num;
    }
}

在默認(rèn)工程的MainActivity添加兩個(gè)JNI方法聲明第一個(gè)為成員訪問,第二個(gè)靜態(tài)方法其兴。他們?cè)贘NI層的生成的代碼是不一樣的。在成員實(shí)例方法jni方法中的前兩個(gè)參數(shù) : JNIEnv env, jobject thiz元旬。thiz代表著所在java類的實(shí)例搁拙。例如本例中是MainActivity的java實(shí)例。取決于這個(gè)方法生命在哪個(gè)類中。

public native void accessField(Person person);

在static 的 jni方法中的前兩個(gè)參數(shù) : JNIEnv *env, jclass clazz酪碘。clazz代表著所在java類朋譬。例如本例中是MainActivity的java類兴垦。取決于這個(gè)方法生命在哪個(gè)類中徙赢。

public static native void accessStaticField(Person person);

接下來在jni中訪問Person類的成員變量:

extern "C"
JNIEXPORT void JNICALL
Java_com_memetghini_javaobject_MainActivity_accessField(JNIEnv *env, jobject thiz, jobject person) {
    //成員變量
    //首先找到類探越,參數(shù)是jni對(duì)象
    jclass cls = env->GetObjectClass(person);
    //再找到成員變量字段id。第一個(gè)參數(shù)是上面找到的類钦幔,第二個(gè)參數(shù)是字段名枕屉,第三個(gè)參數(shù)為字段簽名
    jfieldID fid = env->GetFieldID(cls, "name", "Ljava/lang/String;");
    //為該成員變量設(shè)值鲤氢,第一個(gè)參數(shù)為jni對(duì)象西潘,第二個(gè)參數(shù)為要設(shè)值的字段id,第三個(gè)參數(shù)為具體的值
    jstring str = env->NewStringUTF("Kadi");
    env->SetObjectField(person, fid, str);

    //成員對(duì)象
    //上面已經(jīng)找到了類哨颂,所以先直接找到字段id
    jfieldID house_fid = env->GetFieldID(cls, "house", "Lcom/memetghini/javaobject/House;");
    //再找jni對(duì)象,再?gòu)膶?duì)象中獲取字段值或者更改內(nèi)容威恼,接下來的跟上面相似
    jobject house_obj = env->GetObjectField(person, house_fid);
    jclass house_cls = env->GetObjectClass(house_obj);
    jfieldID size_fid = env->GetFieldID(house_cls, "size", "I");
    env->SetIntField(house_obj, size_fid, 1000000);
}


extern "C"
JNIEXPORT void JNICALL
Java_com_memetghini_javaobject_MainActivity_accessStaticField(JNIEnv *env, jclass clazz, jobject person) {
    //靜態(tài)變量的讀取也是一樣的先通過GetStaticFieldID獲取靜態(tài)變量的字段id
    jfieldID num_fid = env->GetStaticFieldID(clazz, "num", "I");
    //在用靜態(tài)變量的字段id獲取具體的值品姓。第一個(gè)變量為類類型箫措,第二個(gè)為靜態(tài)變量字段id
    int num = env->GetStaticIntField(clazz, num_fid);
    LOGI("jni num main = %d", num);
    //更改靜態(tài)變量的值。第一個(gè)參數(shù)為類類型蒂破,第二個(gè)為靜態(tài)變量字段id馏谨,第三個(gè)為具體的值
    env->SetStaticIntField(clazz, num_fid, 777);
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末附迷,一起剝皮案震驚了整個(gè)濱河市惧互,隨后出現(xiàn)的幾起案子喇伯,更是在濱河造成了極大的恐慌,老刑警劉巖稻据,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艾猜,死亡現(xiàn)場(chǎng)離奇詭異捻悯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)今缚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門算柳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姓言,“玉大人瞬项,你說我怎么就攤上這事何荚。” “怎么了餐塘?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵妥衣,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我称鳞,道長(zhǎng),這世上最難降的妖魔是什么冈止? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任狂票,我火速辦了婚禮熙暴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘周霉。我一直安慰自己掂器,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布国瓮。 她就那樣靜靜地躺著,像睡著了一般狞谱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上跟衅,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天孵睬,我揣著相機(jī)與錄音伶跷,去河邊找鬼掰读。 笑死叭莫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雇初。 我是一名探鬼主播雾狈,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼抵皱,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了呻畸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤悼院,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绞愚,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叙甸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年位衩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糖驴。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡僚祷,死狀恐怖贮缕,靈堂內(nèi)的尸體忽然破棺而出辙谜,到底是詐尸還是另有隱情感昼,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布定嗓,位于F島的核電站蜕琴,受9級(jí)特大地震影響蜕乡,放射性物質(zhì)發(fā)生泄漏奸绷。R本人自食惡果不足惜层玲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辛块。 院中可真熱鬧畔派,春花似錦、人聲如沸润绵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽憨愉。三九已至卿捎,卻和暖如春配紫,著一層夾襖步出監(jiān)牢的瞬間午阵,已是汗流浹背躺孝。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惧眠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓于个,卻偏偏與公主長(zhǎng)得像氛魁,于是被迫代替她去往敵國(guó)和親览濒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子呆盖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 之前寫了一篇文章簡(jiǎn)單的介紹了Android NDK的組件和結(jié)構(gòu)应又,以及在Android studio中開發(fā)ND...
    codeteenager閱讀 1,161評(píng)論 0 2
  • 好久沒發(fā)文章了,這篇文章是是10月底開始計(jì)劃的乏苦,轉(zhuǎn)眼到現(xiàn)在12月都快過一半了株扛,我太難了……汇荐,不過好在終于完成了洞就,今...
    aserbao閱讀 711評(píng)論 0 5
  • JNI 作為 Java/Kotlin(原生端) 同 C/C++ 端交互的工具掀淘,是學(xué)習(xí) ffmpeg 的一個(gè)前提,這...
    Kuky_xs閱讀 613評(píng)論 1 5
  • 靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè) 看下基本的jni的demo革娄,我的java代碼 多說兩句倾贰,就是可能引入jni.h 的時(shí)候不存在需...
    zcwfeng閱讀 234評(píng)論 0 1
  • 0.要素1.類操作2.異常操作3.全局及局部引用4.對(duì)象操作5.字符串操作6.數(shù)組操作7.訪問對(duì)象的屬性和方法7....
    MagicalGuy閱讀 1,343評(píng)論 0 2