java JNI 静态和动态注册的区别

静态注册

原理:根据函数名来建立 java 方法与 JNI 函数的一一对应关系;

实现流程:

编写 java 代码;

利用 javah 指令生成对应的 .h 文件;

对 .h 中的声明进行实现;

弊端:

编写不方便,JNI 方法名字必须遵循规则且名字很长;

编写过程步骤多,不方便;

程序运行效率低,因为初次调用native函数时需要根据根据函数名在JNI层中搜索对应的本地函数,然后建立对应关系,这个过程比较耗时;

动态注册

原理:利用 RegisterNatives 方法来注册 java 方法与 JNI 函数的一一对应关系;

实现流程:

利用结构体 JNINativeMethod 数组记录 java 方法与 JNI 函数的对应关系;

实现 JNI_OnLoad 方法,在加载动态库后,执行动态注册;

调用 FindClass 方法,获取 java 对象;

调用 RegisterNatives 方法,传入 java 对象,以及 JNINativeMethod 数组,以及注册数目完成注册;

动态注册方式:

1:第一步先实现JNI_OnLoad方法(利用 RegisterNatives 方法来注册 java 方法与 JNI 函数的一一对应关系)

static const char* mClassName="com/demo/jnitest/MainActivity";

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)extern "C" JNIEXPORT jint  JNICALL

JNI_OnLoad(JavaVM *vm,void *reserved){

LOGI("JNI_OnLoad");

    _vm=vm;

    JNIEnv *jniEnv;

    jint r = vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6);

    if (r!=JNI_OK){

return -1;

    }

jclass pJclass = jniEnv->FindClass(mClassName);

    if(pJclass==NULL){

printf("cannot get class:%s\n", mClassName);

        return -1;

    }

//注册

    jniEnv->RegisterNatives(pJclass,getMethod, sizeof(getMethod)/sizeof(JNINativeMethod));

    return JNI_VERSION_1_6;

}

2:利用结构体 JNINativeMethod 数组记录 java 方法与 JNI 函数的对应关系

static const JNINativeMethod getMethod[]{

{"javaAdd","(II)I",(jint *)C_Add},

};

其中testThread是在Activity页面声明好的native函数。

public native int javaAdd(int a,int b);

方法初始化调用:

extern "C" JNIEXPORT jint JNICALL

C_Add(JNIEnv *env,

        jobject jobject1,

        jint a,

        jint b){

return a+b;

}

你可能感兴趣的:(java JNI 静态和动态注册的区别)