JNI学习---注册native函数

注册native函数有两种方法:静态注册和动态注册。

静态注册方法

根据函数名找到对应的JNI函数,Java层调用函数时,会从对应的JNI中寻找该函数,如果没有就会报错,如果存在则会建立一个关联联系,以后在调用时会直接使用这个函数,这部分的操作由虚拟机完成。

静态方法就是根据函数名来遍历java和jni函数之间的关联,而且要求jni层函数的名字必须遵循特定的格式,其缺点在于:

  • javah生成的jni层函数特别长;
  • 初次调用native函数时要根据名字搜索对应的jni层函数来建立关联联系,这样影响效率。

动态注册方法

JNI 允许你提供一个函数映射表,注册给Jave虚拟机,这样Jvm就可以用函数映射表来调用相应的函数,就可以不必通过函数名来查找需要调用的函数了。

JNI_OnLoad()函数

JNI_OnLoad()函数在VM执行System.loadLibrary(xxx)函数时被调用,它有两个重要的作用:

  • 指定JNI版本:告诉VM该组件使用那一个JNI版本(若未提供JNI_OnLoad()函数,VM会默认该使用最老的JNI 1.1版),如果要使用新版本的JNI,例如JNI 1.4版,则必须由JNI_OnLoad()函数返回常量JNI_VERSION_1_4(该常量定义在jni.h中) 来告知VM。
  • 初始化设定:当VM执行到System.loadLibrary()函数时,会立即先呼叫JNI_OnLoad()方法,因此在该方法中进行各种资源的初始化操作最为恰当。

RegisterNatives

RegisterNatives在AndroidRunTime里定义:

jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)

clazz:Java类对象
Methods:类中的本地方法
nMethods:类中的本地方法数

总结

本地方法注册相较于函数名映射的好处是不需要使用javah生成一个C++头文件,也不必使用javah自动生成的长长的C++函数名,往往在native函数很多的情况下,扩展比较灵活。同时,Java虚拟机不需要进行映射处理,极大提高运行速度、提升运行效率。

猜你喜欢

转载自blog.csdn.net/johnWcheung/article/details/129441596