【Tech-Android-Jni】Jni的基本方法(1)

1.生成頭文件
首先通過編寫本地函數native的方法,利用javah 指令生成C的頭文件。一般的頭文件會給出所已經定義好的方法。
例如下列:
JNIEXPORT void JNICALL Java_com_example_adder_actNative_nativeExec(JNIEnv *, jclass);(頭文件)
這裏就包含了一個actNative類中的一個返回值爲空的nativeExec的方法。

2.根據這個方法定義可以寫出c的文件。

JNIEXPORT void JNICALL Java_com_example_adder_actNative_nativeExec
  (JNIEnv *env, jclass thiz){
      第一個參數爲這個c文件的指針,第二個參數是呼叫C函數的Java層的對象(是一個reference).
      可以根據:
      jclass  clazz = (*env)->GetObjectClass(env thiz);(該方法獲取java層的對象) 稱之喂類別指針。 
      //由於thiz只是一個參考對象類別,該對象類別在該方法結束的時候會給刪除掉,所以要將其轉爲全局參考變量
       m_jclass = (jclass)(*env)->NewGlobalRef(env,clazz );

      //同理可以得到thiz參考類的全局變量
      m_jobject = (jobject)(*env)->NewGlobalRef(env,thiz);
     //同理可以得到該參考類別的字段名,並將其存入C函數中
      m_fid  = (*env)->GetFieldID(env,clazz,"numb","I");//注意 這裏利用的是clazz ,就是java層的reference.非全局參考變量。
     //再獲得java層中的函數方法
     m_rv_mid = (*env)->GetMethodID(env,m_jclass ,"setV","(I)V");//注意 這裏利用的是全局參考變量。m_jclass.
    //如果java層中的的setV()方法是靜態的話,則利用GetStaticMethodId()方法。

     //獲取一個字段中的值 例如一個整形n
     n = (int)(*env)->GetObjectField(env,m_object,m_mid);
     //m_mid爲已經在java層獲取過來的字段ID,通過getFieldID的方法獲取。

3.在C函數中如何調用java層的方法呢?
(*env)->CallVoidMethod(env,m_jobject,m_mid,sum);
m_jobject代表了正指向java層目前對象的的關聯全局參考。m_mid儲存了方法名的ID,sum是要給方法 函數存入值。
如果方法是一個靜態的話,利用 CallStaticViodMethod();

總結:
1.獲取java中的字段ID,方法ID並存入C函數中的話,要利用clazz,通過GetObjectClass(),獲取類別指針。
2.獲取字段中的值,或調用Java層的方法時候,利用m_jobject,通過NewGlobalRef(env,thiz)獲取。

以上爲入門JNI的一些總結,對C不是很熟悉,我知道一定有錯,但會一直學習下去。邊學邊改正,也 望指出。

發佈了79 篇原創文章 · 獲贊 43 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章