1. 程式人生 > >android jni 中常使用的函式及用法

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代表的是幾維陣列。

  1. String型別的域描述符為 Ljava/lang/String;    
  2. [ + 其型別的域描述符 + ;  
  3. int[ ]     其描述符為[I  
  4. float[ ]   其描述符為[F  
  5. String[ ]  其描述符為[Ljava/lang/String;  
  6. Object[ ]型別的域描述符為[Ljava/lang/Object;  
  7. int  [ ][ ] 其描述符為[[I  
  8. float[ ][ ] 其描述符為[[F  

 將引數型別的域描述符按照申明順序放入一對括號中後跟返回值型別的域描述符,規則如下: (引數的域描述符的疊加)返回型別描述符。對於,沒有返回值的,用V(表示void型)表示。
舉例如下:

  1. Java層方法                                               JNI函式簽名  
  2.                 String test ( )                                              Ljava/lang/String;  
  3.                 int f (int i, Object object)                            (ILjava/lang/Object;)I  
  4.                 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。