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

相关文章
相关标签/搜索