JNI 基礎(chǔ)知識(shí)
什么是 JNI ?
JNI (Java Native Interface) 是 Java 溝通 Native 語(yǔ)言(主要是C、C++)的橋梁。
Native 語(yǔ)言有著更高的性能,更重要的是還有龐大的 Native 語(yǔ)言所編寫(xiě)的庫(kù)重荠。
這些給 Java 語(yǔ)言提供很多性能優(yōu)秀的強(qiáng)大功能支持。
JNI 能夠提供 Java 更快速的 Native 功能移植虚茶,也能利用 C++ 的反匯編能力加強(qiáng)代碼安全性戈鲁。
JNI 數(shù)據(jù)類型與 Java 、C++ 類型對(duì)比
Java 使用 JNI 最主要連接的 Native 語(yǔ)言是 C嘹叫、C++(C++可以兼容C)婆殿。
因此這里介紹 Java 類型與 JNI 類型和 C++ 類型的對(duì)比關(guān)系。
Java 類型 | JNI 類型 | C++ 類型(包含封裝的部分) |
---|---|---|
int |
jint / jsize |
long |
long |
jlong |
__int64 |
byte |
jbyte |
signed char |
boolean |
jboolean |
unsigned char |
char |
jchar |
unsigned short |
short |
jshort |
short |
float |
jfloat |
float |
double |
jdouble |
double |
Object |
jobject |
_jobject* |
Java 其它數(shù)據(jù)類型與 JNI 的關(guān)系
Java 還具有其它基礎(chǔ)類型罩扇,為了方便調(diào)用也需要有 JNI 的類型進(jìn)行對(duì)應(yīng)婆芦。
基于常用的類型,有以下關(guān)系喂饥。
所有的 Class 都繼承于 jobject消约,但是由于層次不一樣。
不同的 jobject 的子類型有著不同的獲取员帮、調(diào)用和釋放方式或粮。
JNI 各種對(duì)象的方法
方法 | 說(shuō)明 |
---|---|
FindClass |
加載本地定義的類 |
GetObjectClass |
通過(guò)對(duì)象獲取這個(gè)類 |
NewObject |
創(chuàng)建 jobject 類型的對(duì)象 |
NewString |
創(chuàng)建 jstring 類型的對(duì)象 |
DeleteLocalRef |
刪除局部引用 |
DeleteGlobalRef |
刪除全局引用 |
New<Type>Array |
創(chuàng)建類型為 Type 的數(shù)組對(duì)象 |
Get<Type>ArrayElements |
從類型為 Type 的數(shù)組對(duì)象獲取類型為 Type 的數(shù)組指針 |
Release<Type>ArrayElements |
根據(jù)類型為 Type 的數(shù)組對(duì)象釋放類型為 Type 的數(shù)組指針指向的資源 |
Get<Type>Field |
獲取類型為 Type 的字段 |
GetStatic<Type>Field |
獲取類型為 Type 的 static 字段 |
Set<Type>Field |
設(shè)置類型為 Type 的字段 |
SetStatic<Type>Field |
設(shè)置類型為 Type 的 static 字段 |
Call<Type>Method |
調(diào)用類型為 Type 的方法 |
CallStatic<Type>Method |
調(diào)用類型為 Type 的 static 方法 |
還有很多與類有關(guān)的方法,利用的頻率不高就先不添加了捞高。
JNI 域描述符
Java 類型 | JNI 類型 | 域描述符 | 說(shuō)明 | 示例 |
---|---|---|---|---|
boolean | jboolean | Z | ||
byte | jbyte | B | ||
char | jchar | C | ||
short | jshort | S | ||
int | jint | I | ||
long | jlong | J | ||
float | jfloat | F | ||
double | jdouble | D | ||
int[] | [I | 一維數(shù)組形式氯材,以一個(gè) "[" 表示一維數(shù)組 | ||
byte[][] | [[B | N 維數(shù)組則以 N 個(gè) "[" 表示N維 | ||
String | jstring | Ljava/lang/String; | 類參數(shù)渣锦,則以 "Lxxx/yyy;" 的形式表示,注意 "L" 開(kāi)頭和 ";" 結(jié)尾浓体。xxx/yyy 則是類的路徑(都屬于 jobject ) | |
返回值 void | V | |||
函數(shù)形式 | (xxx)yyy | "()"內(nèi)為輸入?yún)?shù)泡挺,右側(cè)為輸出參數(shù) |
JNI 內(nèi)存泄漏檢查
由于 JNI 的機(jī)制,凡是創(chuàng)建 jobject 對(duì)象(包括其派生)命浴,都會(huì)在 Heap 申請(qǐng)資源。
及時(shí)不使用 jobject 對(duì)象贱除,也會(huì)有資源占用生闲。
導(dǎo)致退出時(shí)需要對(duì) JNI 內(nèi)的 jobject 對(duì)象資源釋放。
(如果 jobject 返回到 Java 接口中月幌,由 Java 進(jìn)行回收)
對(duì)于新手的 JNI 開(kāi)發(fā)來(lái)說(shuō)碍讯,內(nèi)存泄漏可能是必然存在的情況。
檢查內(nèi)存泄漏可以使用如下 adb 命令:
adb shell dumpsys meminfo packageName
檢查 Native Heap 項(xiàng)扯躺,如下圖捉兴。