借助于javah工具,该工具会在编译时对每个class文件中声明了native的函数输出一份。h头文件,在头文件中定义了这些函数对应的jni层的函数指针。
当java调用native的函数时,会在头文件中寻找对应的jni函数指针,然后进行保存起来映射关系。 也就是编译为每个class生产一份h头文件,头文件中存储对应java方法的native函数指针,在运行时调用jni函数时,进行查找对应的函数指针运行,接着进行关系映射缓存起来下次进来找到对应的直接运行指针即可。
编译时需要为每个class生产一份h头文件,第一次使用时还需要先去头文件中查找才能运行。虽说后面会快有缓存
顾名思义,上面建立缓存是在第一次加载后才会建立映射。如果我们能够提前知道java中的函数对应的是哪个jni函数那么久不需要上面那么麻烦的过程了(先编译生产头文件,运行时在找在确定函数指针;
而loadlibrary函数调用时会去首先寻找so库中的load函数,我们可以在这个函数中进行java函数和native函数指针绑定的过程。
java函数名称,签名信息,jni层对应函数指针,属于哪个类的java函数。知道这些信息将其注册到一个映射表中。
后期运行时根据函数名称签名信息所属类就可以找到对应的jni函数指针。
一个是运行时生产在so库加载的时候就进行映射。java和对应jni函数的关系存储到表中。这种由于不需要根据java方法名来找jni函数名因此其jni函数可以更简洁。
一个是先造编译时定义jni函数指针,之后运行时根据函数信息在找在缓存映射运行,因为后期要根据java方法名称来找对应jni函数的指针,所以jni函数的定义要和java方法对应。类名-方法名会很长。而且编译时会生产很多h头文件进行存储这些超长名字的jni函数指针我,所以不是很优雅。