Android JNI學習-函數動態註冊

前面JNI開發相關的也寫了幾篇博客,對java中native關鍵字定義的方法進行註冊時,都是使用Javah命令生成對應的Java _ 包名 _ 類名 _ 方法名,如今徹底能夠經過編譯器幫咱們生成,咱們去填對應的邏輯代碼便可,這種方式被稱爲靜態註冊。今天來看一下新的方式:動態註冊java

不一樣於靜態註冊中在Java類中定義好native方法後由編譯器生成JNI方法,動態註冊基本思想是在JNI_Onload()函數中經過JNI中提供的RegisterNatives()方法來將C/C++方法和java方法對應起來, JNI_OnLoad ()函數會在咱們調用 System.loadLibrary的時候回調,註冊總體流程以下:c++

  1. 定義Java類中的native方法
  2. 編寫C/C++代碼, 實現JNI_Onload()方法
  3. 將Java 方法和 C/C++方法經過簽名信息對應起來
  4. 經過JavaVM獲取JNIEnv, JNIEnv主要用於獲取Java類和調用一些JNI提供的方法
  5. 使用類名和對應起來的方法做爲參數, 調用JNI提供的函數RegisterNatives()註冊方法

一、Java Native方法

public native String getStringFromC();

public native int getIntFromC(int index);
複製代碼

二、C/C++方法

jstring returnString(JNIEnv *env, jobject instance) {
    char *str = "I come from C++";
    return env->NewStringUTF(str);
}

jint returnInt(JNIEnv *env, jobject instance, jint index) {
    return index + 10;
}
複製代碼

三、JNINativeMethod

static JNINativeMethod gMethods[] = {
        {"getStringFromC", "()Ljava/lang/String;", (void *) returnString},
        {"getIntFromC",    "(I)I",                 (void *) returnInt}
};
複製代碼
  • 第一個參數對應的native方法名
  • 第二個參數對應 native方法的描述
  • 第三個參數對應的c++代碼裏對應的實現

經過這個數組將Java層函數和C/C++層代碼對應起來數組

四、JNI_Onload

int JNI_OnLoad(JavaVM *vm, void *re) {
    JNIEnv *env;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        return JNI_ERR;
    }

    jclass javaClass = env->FindClass("com/david/jnitestdemo/MainActivity");
    if (javaClass == NULL) {
        return JNI_ERR;
    }
    if (env->RegisterNatives(javaClass, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
        return JNI_ERR;
    }
    return JNI_VERSION_1_6;
}
複製代碼

env->RegisterNatives(javaClass, gMethods, sizeof(gMethods) / sizeof(gMethods[0])markdown

第一個表示對應jclass,第二個表示JNINativeMethod的數組,第三個是函數的數量函數

這樣就完成了簡單的JNI動態註冊Demothis

對比下以前的靜態註冊:spa

//靜態註冊
extern "C" JNIEXPORT jstring JNICALL Java_com_david_jnitestdemo_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) {
}
 
//動態註冊
jstring returnString(JNIEnv *env, jobject instance) {
}
複製代碼

相比較來講動態註冊的代碼會清爽一些,雖然多了JNI_OnLoad和JNINativeMethod,可是JNI_OnLoad基本能夠只寫一次,JNINativeMethod每次有新增函數時才修改,因此我的感受動態註冊寫代碼會更舒服些,也看我的習慣 ,好了就到這裏了。 ^-^code

相關文章
相關標籤/搜索