Android 实现JNI动态注册

Android 实现JNI的动态注册

  • 前景
  • 什么是静态注册
    • 静态注册的优缺点
      • 优点
      • 缺点
  • 什么是动态注册
    • 实现
    • 创建步骤
      • 用到的方法
  • 结束

前景

JNI可以说是Java 和Native 的桥梁 起承上启下的作用,没有JNI Android就只能访问到Java 的Framework层,在想深入可谓是举步维艰.

什么是静态注册

静态注册就是根据函数名来建立Java函数与JNI函数一一对应的关系
JNI函数名的规则:Java_包名_类名_函数名,也就是以这种规则来确认JNI函数与某个类Java函数的对应关系
在Java加载so库的时候会吧JNI的方法链接过来,无论你用还是不用,此方法都已经存在比较浪费内存

静态注册的优缺点

优点

方便,快捷,省心,不易出错,

缺点

不能轻易修改包名,JNI函数名过长,不灵活

什么是动态注册

动态注册是在JNI里面存在一张JNI函数与Java函数的映射表,然后把这张表丢给JavaVM,JavaVM就可以通过这张表去寻找JNI函数,而不是通过函数名的规则去遍历JNI函数,动态注册的效率更高,更清晰可控.

实现

在java引用的cpp库文件里会存在一个JNI_OnLoad函数,这个函数就像Java的构造函数一样,如果不重写,JNI会默认存在.
Android 实现JNI动态注册_第1张图片
在Java 代码中通过加载库文件,就会加载JNI_OnLoad()方法,若不重写则会默认存在

创建步骤

用到的方法

JNINativeMethod 结构体 这个结构体基本上都是以数组的形式进行使用

typedef struct {
     
    const char* name; // Java函数名
    const char* signature; //Java函数签名
    void*       fnPtr;  //JNI函数指针
} JNINativeMethod;

RegisterNatives 注册JNI与Java对应关系

//返回int类型 0代表成功 
jint RegisterNatives(jclass clazz,//注册那个Java类的native函数
 const JNINativeMethod* methods, //上面的结构体
 jint nMethods  //注册多少个函数
 )
    {
      return functions->RegisterNatives(this, clazz, methods, nMethods); }

在native-lib.cpp文件中重写JNI_OnLoad()方法

JNIEXPORT jint JNI_OnLoad(JavaVM *javaVm, void *) {}

//JNI函数
jstring dynamicMethod(JNIEnv *env, jobject thiz, jstring str) {
       
}


//+++++++++++++++++++++++++++++++++++++++++++++++[动态注册代码]
JavaVM *javaVm; //全局的JavaVM
const char *mainActivityName = "com/json/new_jni_pproject_11_1/MainActivity"; //注册的Java类包名
//Java函数名与JNI函数名对应关系
const JNINativeMethod jniNativeMethod[] =
        {
     
                {
     "dynamicMethod", "(Ljava/lang/String;)Ljava/lang/String;", (jstring *) (dynamicMethod)}
        };

JNIEXPORT jint JNI_OnLoad(JavaVM *javaVm, void *) {
     

    ::javaVm = javaVm; //:: 表示域 与this类似
    JNIEnv *env = nullptr;
    javaVm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);//实例化JNIEnv

    jclass mainActivityClass = env->FindClass(mainActivityName);

	//进行注册
   jint result= env->RegisterNatives(mainActivityClass, jniNativeMethod,
                         sizeof(jniNativeMethod) / sizeof(JNINativeMethod));

if(result!=JNI_OK)
{
     
	LOGI("动态函数   初始化失败");
}
    LOGI("动态函数   初始化完成");
    return JNI_VERSION_1_6;

}

结束

你可能感兴趣的:(Android,android,jni)