android jni 中常使用的函式及用法
http://blog.csdn.net/banketree/article/details/40535325
Java型別 | 本地型別(JNI) | 描述 |
boolean(布林型) | jboolean | 無符號8個位元 |
byte(位元組型) | jbyte | 有符號8個位元 |
char(字元型) | jchar | 無符號16個位元 |
short(短整型) | jshort | 有符號16個位元 |
int(整型) | jint | 有符號32個位元 |
long(長整型) | jlong | 有符號64個位元 |
float(浮點型) | jfloat | 32個位元 |
double(雙精度浮點型) | jdouble | 64個位元 |
void(空型) | void | N/A |
函式操作
函式 | Java 陣列型別 | 本地型別 | 說明 |
GetBooleanArrayElements | jbooleanArray | jboolean | ReleaseBooleanArrayElements 釋放 |
GetByteArrayElements | jbyteArray | jbyte | ReleaseByteArrayElements 釋放 |
GetCharArrayElements | jcharArray | jchar | ReleaseShortArrayElements 釋放 |
GetShortArrayElements | jshortArray | jshort | ReleaseBooleanArrayElements 釋放 |
GetIntArrayElements | jintArray | jint | ReleaseIntArrayElements 釋放 |
GetLongArrayElements | jlongArray | jlong | ReleaseLongArrayElements 釋放 |
GetFloatArrayElements | jfloatArray | jfloat | ReleaseFloatArrayElements 釋放 |
GetDoubleArrayElements | jdoubleArray | jdouble | ReleaseDoubleArrayElements 釋放 |
GetObjectArrayElement | 自定義物件 | object | |
SetObjectArrayElement | 自定義物件 | object | |
GetArrayLength | 獲取陣列大小 | ||
New<Type>Array | 建立一個指定長度的原始資料型別的陣列 | ||
GetPrimitiveArrayCritical | 得到指向原始資料型別內容的指標,該方法可能使垃圾回收不能執行,該方法可能返回陣列的拷貝,因此必須釋放此資源。 | ||
ReleasePrimitiveArrayCritical | 釋放指向原始資料型別內容的指標,該方法可能使垃圾回收不能執行,該方法可能返回陣列的拷貝,因此必須釋放此資源。 | ||
NewStringUTF | jstring型別的方法轉換 | ||
GetStringUTFChars | jstring型別的方法轉換 | ||
DefineClass | 從原始類資料的緩衝區中載入類 | ||
FindClass | 該函式用於載入本地定義的類。它將搜尋由CLASSPATH 環境變數為具有指定名稱的類所指定的目錄和 zip檔案 | ||
GetObjectClass | 通過物件獲取這個類。該函式比較簡單,唯一注意的是物件不能為NULL,否則獲取的class肯定返回也為NULL | ||
GetSuperclass | 獲取父類或者說超類 。 如果 clazz 代表類class而非類 object,則該函式返回由 clazz 所指定的類的超類。 如果 clazz指定類 object 或代表某個介面,則該函式返回NULL | ||
IsAssignableFrom | 確定 clazz1 的物件是否可安全地強制轉換為clazz2 | ||
Throw | 丟擲 java.lang.Throwable 物件 | ||
ThrowNew | 利用指定類的訊息(由 message 指定)構造異常物件並丟擲該異常 | ||
ExceptionOccurred | 確定是否某個異常正被丟擲。在平臺相關程式碼呼叫 ExceptionClear() 或 Java 程式碼處理該異常前,異常將始終保持丟擲狀態 | ||
ExceptionDescribe | 將異常及堆疊的回溯輸出到系統錯誤報告通道(例如 stderr)。該例程可便利除錯操作 | ||
ExceptionClear | 清除當前丟擲的任何異常。如果當前無異常,則此例程不產生任何效果 | ||
FatalError | 丟擲致命錯誤並且不希望虛擬機器進行修復。該函式無返回值 | ||
NewGlobalRef | 建立 obj 引數所引用物件的新全域性引用。obj 引數既可以是全域性引用,也可以是區域性引用。全域性引用通過呼叫DeleteGlobalRef() 來顯式撤消。 | ||
DeleteGlobalRef | 刪除 globalRef 所指向的全域性引用 | ||
DeleteLocalRef | 刪除 localRef所指向的區域性引用 | ||
AllocObject | 分配新 Java 物件而不呼叫該物件的任何建構函式。返回該物件的引用。clazz 引數務必不要引用陣列類。 | ||
getObjectClass | 返回物件的類 | ||
IsSameObject | 測試兩個引用是否引用同一 Java 物件 | ||
NewString | 利用 Unicode 字元陣列構造新的 java.lang.String 物件 | ||
GetStringLength | 返回 Java 字串的長度(Unicode 字元數) | ||
GetStringChars | 返回指向字串的 Unicode 字元陣列的指標。該指標在呼叫 ReleaseStringchars() 前一直有效 | ||
ReleaseStringChars | 通知虛擬機器平臺相關程式碼無需再訪問 chars。引數chars 是一個指標,可通過 GetStringChars() 從 string 獲得 | ||
NewStringUTF | 利用 UTF-8 字元陣列構造新 java.lang.String 物件 | ||
GetStringUTFLength | 以位元組為單位返回字串的 UTF-8 長度 | ||
GetStringUTFChars | 返回指向字串的 UTF-8 字元陣列的指標。該陣列在被ReleaseStringUTFChars() 釋放前將一直有效 | ||
ReleaseStringUTFChars | 通知虛擬機器平臺相關程式碼無需再訪問 utf。utf 引數是一個指標,可利用 GetStringUTFChars() 獲得 | ||
NewObjectArray | 構造新的陣列,它將儲存類 elementClass 中的物件。所有元素初始值均設為 initialElement | ||
Set<PrimitiveType>ArrayRegion | 將基本型別陣列的某一區域從緩衝區中複製回來的一組函式 | ||
GetFieldID | 返回類的例項(非靜態)域的屬性 ID。該域由其名稱及簽名指定。訪問器函式的 Get<type>Field 及 Set<type>Field系列使用域 ID 檢索物件域。GetFieldID() 不能用於獲取陣列的長度域。應使用GetArrayLength()。 |
||
Get<type>Field | 該訪問器例程系列返回物件的例項(非靜態)域的值。要訪問的域由通過呼叫GetFieldID() 而得到的域 ID 指定。 | ||
Set<type>Field | 該訪問器例程系列設定物件的例項(非靜態)屬性的值。要訪問的屬性由通過呼叫 SetFieldID() 而得到的屬性 ID指定。 |
||
GetStaticFieldID GetStatic<type>Field SetStatic<type>Field |
同上,只不過是靜態屬性。 | ||
GetMethodID | 返回類或介面例項(非靜態)方法的方法 ID。方法可在某個 clazz 的超類中定義,也可從 clazz 繼承。該方法由其名稱和簽名決定。 GetMethodID() 可使未初始化的類初始化。要獲得建構函式的方法 ID,應將<init> 作為方法名,同時將void (V) 作為返回型別。 | ||
CallVoidMethod | |||
CallObjectMethod | |||
CallBooleanMethod | |||
CallByteMethod | |||
CallCharMethod | |||
CallShortMethod | |||
CallIntMethod | |||
CallLongMethod | |||
CallFloatMethod | |||
CallDoubleMethod | |||
GetStaticMethodID | 呼叫靜態方法 | ||
Call<type>Method | |||
RegisterNatives | 向 clazz 引數指定的類註冊本地方法。methods 引數將指定 JNINativeMethod 結構的陣列,其中包含本地方法的名稱、簽名和函式指標。nMethods 引數將指定陣列中的本地方法數。 | ||
UnregisterNatives | 取消註冊類的本地方法。類將返回到連結或註冊了本地方法函式前的狀態。該函式不應在常規平臺相關程式碼中使用。相反,它可以為某些程式提供一種重新載入和重新連結本地庫的途徑。 |
域描述符
域 | Java 語言 |
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
引用型別則為 L + 該型別類描述符 + 。
陣列,其為 : [ + 其型別的域描述符 + 。
多維陣列則是 n個[ +該型別的域描述符 , N代表的是幾維陣列。
- String型別的域描述符為 Ljava/lang/String;
- [ + 其型別的域描述符 + ;
- int[ ] 其描述符為[I
- float[ ] 其描述符為[F
- String[ ] 其描述符為[Ljava/lang/String;
- Object[ ]型別的域描述符為[Ljava/lang/Object;
- int [ ][ ] 其描述符為[[I
- float[ ][ ] 其描述符為[[F
將引數型別的域描述符按照申明順序放入一對括號中後跟返回值型別的域描述符,規則如下: (引數的域描述符的疊加)返回型別描述符。對於,沒有返回值的,用V(表示void型)表示。
舉例如下:
- Java層方法 JNI函式簽名
- String test ( ) Ljava/lang/String;
- int f (int i, Object object) (ILjava/lang/Object;)I
- void set (byte[ ] bytes) ([B)V
JNIEnv與JavaVM
JNIEnv 概念 : 是一個執行緒相關的結構體, 該結構體代表了 Java 在本執行緒的執行環境 ;
JNIEnv 與 JavaVM : 注意區分這兩個概念;
-- JavaVM : JavaVM 是 Java虛擬機器在 JNI 層的代表, JNI 全域性只有一個;
-- JNIEnv : JavaVM 線上程中的代表, 每個執行緒都有一個, JNI 中可能有很多個 JNIEnv;
JNIEnv 作用 :
-- 呼叫 Java 函式 : JNIEnv 代表 Java 執行環境, 可以使用 JNIEnv 呼叫 Java 中的程式碼;
-- 操作 Java 物件 : Java 物件傳入 JNI 層就是 Jobject 物件, 需要使用 JNIEnv 來操作這個 Java 物件;
JNIEnv 體系結構
執行緒相關 : JNIEnv 是執行緒相關的, 即 在 每個執行緒中 都有一個 JNIEnv 指標, 每個JNIEnv 都是執行緒專有的, 其它執行緒不能使用本執行緒中的 JNIEnv, 執行緒 A 不能呼叫 執行緒 B 的 JNIEnv;
JNIEnv 不能跨執行緒 :
-- 當前執行緒有效 : JNIEnv 只在當前執行緒有效, JNIEnv 不能在 執行緒之間進行傳遞, 在同一個執行緒中, 多次呼叫 JNI層方法, 傳入的 JNIEnv 是相同的;
-- 本地方法匹配多JNIEnv : 在 Java 層定義的本地方法, 可以在不同的執行緒呼叫, 因此 可以接受不同的 JNIEnv;
JNIEnv 結構 : 由上面的程式碼可以得出, JNIEnv 是一個指標, 指向一個執行緒相關的結構, 執行緒相關結構指向 JNI 函式指標 陣列, 這個陣列中存放了大量的 JNI 函式指標, 這些指標指向了具體的 JNI 函式;
注意:JNIEnv只在當前執行緒中有效。本地方法不能將JNIEnv從一個執行緒傳遞到另一個執行緒中。相同的 Java 執行緒中對本地方法多次呼叫時,傳遞給該本地方法的JNIEnv是相同的。但是,一個本地方法可被不同的 Java 執行緒所呼叫,因此可以接受不同的 JNIEnv。