JNI接口

JNI是Java Native Interface的英文縮寫,相似一種標準,提供了不少的API,使Java能夠和C/C++進行通訊。而JNI接口正是Java層世界與C/C++語言世界之間的橋樑。java

探究:爲何使用JNI呢?api

1.使用現有的開源庫,如今不少優秀的開源庫都是用C/C++編寫的。數組

2.代碼的保護,Android APK的Java代碼容易被反編譯,而C/C++更難 反編譯。ide

3.便於移植,用C/C++寫的庫能夠方便在其餘嵌入式平臺使用。函數

一:經過JNI接口實現Java層與Native層相互調用編碼

如今來看下面這一張圖,經過這張圖完美的展現JNI接口的規則。 code

首先看到這張圖片左邊部分是熟悉的Java層開發,中間部分是要用到JNI接口來調用相關的C/C++函數。那麼C/C++是怎麼調用Java代碼的呢?這就要用到反射,在JNI接口中提供了不少函數供咱們進行調用。對象

JNI接口

二:JNI接口blog

JNI接口是谷歌開發人員爲了方便Java層與C/C++層進行通訊而對外提供的接口,對應的接口描述文檔在「jni.h」頭文件中。接口

這一排就是JNI接口中的數據類型,數據類型就是在基本數據類型前加了一個字母j而已,記憶起來比較簡單。以下圖所示。

JNI接口

緊接着是對象、數組等類型,以下圖所示。

JNI接口

接下來介紹JNI函數,包含的有如下幾種類型,其中Call開頭的函數字面意思就是調用,這裏指的是經過反射調用Java層方法;Get開頭的函數字面意思就是獲取,這裏指的是經過反射獲取Java層字段的值;Set開頭的函數字面意思就是設置,這裏指的是經過反射修改Java層字段的值;New開頭的就是建立其餘類型的函數。

jclass (FindClass)(JNIEnv, const char*);

jmethodID (GetMethodID)(JNIEnv, jclass, const char, const char);

jobject (CallObjectMethod)(JNIEnv,jobject,jmethodID, ...);

jfieldID (GetFieldID)(JNIEnv, jclass, const char, const char);

jobject (GetObjectField)(JNIEnv, jobject, jfieldID);

void (SetObjectField)(JNIEnv, jobject, jfieldID, jobject);

jmethodID(GetStaticMethodID)(JNIEnv,jclass,const char,constchar);

jobject (CallStaticObjectMethod)(JNIEnv,jclass, jmethodID, ...);

jfieldID (GetStaticFieldID)(JNIEnv,jclass,const char,const char);

jobject (GetStaticObjectField)(JNIEnv, jclass, jfieldID);

void (SetStaticObjectField)(JNIEnv, jclass, jfieldID, jobject);

jstring (NewStringUTF)(JNIEnv, const char*);

接下來對上面的JNI接口函數進行了解。

(1)調用Java層普通方法

Jobject:返回值,這裏返回的是jobject 。

(*CallObjectMethod):這裏調用的是普通方法。

(JNIEnv*,jobject,jmethodID, ...):參數列表信息。

第一參數是JNIEnv*,是本地調用接口,裏面提供大量的JNI接口函數供調用。第二個參數是jobject對象。 第三個參數是方法ID,該參數能夠經過GetMethodID函數獲取。「...」表示的是調用方法的參數列表信息。

探究:什麼是Get MethodID?

使用GetMethodID函數獲取Java層的方法ID,原形以下:

jmethodID:返回值,這裏返回的是Java層方法ID。

(*GetMethodID):獲取普通方法ID。

(JNIEnv, jclass, const char, const char*):參數列表信息。

該函數的第二個參數是jclass,能夠經過FindClass函數獲取。第三個參數是Java層的方法名稱,第四參數是Java層方法的簽名信息。

探究:什麼是FindClass?

FindClass函數經過反射獲取Java類,原形以下:

Jclass:返回值,這裏返回的是java類。

(*FindClass):反射獲取Java類。

(JNIEnv, const char):參數列表信息。

(2)獲取Java層實例字段的值

Jobject:返回值,這裏返回的是jobject 。

(*GetObjectField):獲取Java層實例字段的值。

(JNIEnv*, jobject, jfieldID):參數列表信息。第三參數是實例字段ID,該參數能夠經過GetFieldID函數獲取,原形以下:

jfieldID:返回值,這裏返回的是實例字段ID。

(*GetFieldID):獲取實例字段ID。

(JNIEnv*, jclass, const char*, const char*):參數信息。該函數的第三個參數是實例字段名稱,第四個參數是實例字段的簽名信息。

(3)設置Java層實例字段的值

Void:返回值爲void。

(*SetObjectField):設置Java層實例字段的值。

(JNIEnv*, jobject, jfieldID, jobject):參數信息。第四個參 數爲Java層實例字段要設置的值。

(4)調用Java層靜態方法

Jobject:返回值,這裏返回的是jobject 。

(*CallStaticObjectMethod):這裏調用的是靜態方法。

(JNIEnv,jclass, jmethodID, ...):參數列表信息。第一參數是JNIEnv,是本地調用接口,裏面提供大量的JNI接口函數供咱們調用。第二個參數是jclass。第三個參數是靜態方法ID,該參數能夠經過GetStatic MethodID函數獲取。後面「...」表示的是調用方法的參數列表信息。

探究:什麼是GetStaticMethodID?

使用GetStaticMethodID函數獲取Java層的靜態方法ID,原形以下:

jmethodID :返回值,這裏返回的是Java層方法ID。

(*GetStaticMethodID):獲取靜態方法ID。

(JNIEnv, jclass, const char, const char*):參數列表信息。

該函數的第二個參數是jclass,能夠經過FindClass函數獲取。第三個參數是Java層的方法名稱,第四參數是Java層方法的簽名信息。

(5)獲取Java層靜態字段的值

Jobject:返回值,這裏返回的是jobject 。

(*GetStaticObjectField):獲取Java層靜態字段的值。

(JNIEnv*, jclass, jfieldID): 參數列表信息。第三參數是靜態字段ID,該參數能夠經過GetStaticFieldID函數獲取,原形以下:

jfieldID: 返回值,這裏返回的是實例字段ID。

(*GetStaticFieldID): 獲取靜態字段ID。

(JNIEnv*, jclass, const char*, const char*): 參數信息。該函數的第三個參數是靜態字段名稱,第四個參數是靜態字段的簽名信息。

(6)設置Java層靜態字段的值

void : 返回值爲void。

(*SetStaticObjectField): 設置Java層靜態字段的值。

(JNIEnv*, jclass, jfieldID, jobject):參數信息。第四個參數爲Java層靜態字段要設置的值。

(7)New開頭的函數就是建立,藉助new開頭的函數api建立相應的基本類型、數組、對象,原形:

Jstring:返回值爲jstring。

(*NewStringUTF) :建立utf-8編碼的字符串。

(JNIEnv*, const char*):參數列表信息。第二個就是參數是char*類型的值,在這裏能夠輸入想要建立的字符串。

小結:

JNI接口是實現Java層與C/C++層相互調用,以及經常使用的JNI接口函數和它們的用途,以下表所示。

JNI接口

相關文章
相關標籤/搜索