1 背景
经过NDK开发的入门学习后,顿感自己啥也不是😅😅😅,还是好好学习吧
2 JNI简介
JNI(Java Native Interface)是指Java原生接口,它定义了Android从受管理代码(使用Java或Kotlin编程语言编写)编译的字节码与原生代码(使用C/C++编写)互动的方式。同时,这个特性使我们可以复用以前用C/C++写的大量代码。JNI不依赖于供应商,支持从动态共享库加载代码,虽然有时较为繁琐,但效率尚可。
JNI开发流程主要分为以下6步:
- 编写声明了native方法的Java类
- 将Java源代码编译成class字节码文件
- 用javah -jni命令生成.h头文件(javah是jdk自带的一个命令,-jni参数表示将class中用native声明的函数生成jni规则的函数)
- 用本地代码实现.h头文件中的函数
- 将本地代码编译成动态库(Windows:*.dll,linux/Unix:*.so,Mac OS X:*.jnilib)
- 拷贝动态库至java.library.path本地库搜索目录下,并运行Java程序
3 静态注册和动态注册
为什么需要注册?其实就是给Java的native函数找到底层C/C++实现的函数指针。
3.1 静态注册
通过包名、类名一致来确认,Java有一个命令javah,专门生成某一个JAVA文件所有的native函数的头文件(h文件),静态方法注册JNI有哪些缺点?
- 必须遵循某些规则;
- 名字过长;
- 多个class文件需Javah多遍;
- 运行时去找效率不高
1 | /**************静态方法**********************/ |
【注】在so文件中,静态注册方法的参数个数=Java层方法参数个数+其余参数个数(JNIEnv,jobject)
3.2 动态注册
在JNI层实现的,JAVA层不需要关心,因为在system.load函数执行时就会去调用JNI_OnLoad,有就注册,没就不注册。流程清晰可控,效率更高,安全。
1 | /************************* 动态注册 native 方法 ********************************/ |
【注】在so文件中,动态注册通常先搜索JNI_OnLoad,然后找RegisterNatives的第三个参数,接着找方法数组映射关系
3.3 区别
静态注册:
- 绑定java方法和C/C++方法的方式之一;
- java层操作和c层操作以及整体编译:
- 定义被native修饰的方法
- 根据java代码生成.h头文件(javah -jni 类的包名路径)
- 编写C/C++代码,导入.h头文件,实现我们.h头文件中方法
- 编写(配置)两个mk文件:application.mk/android.mk
- 通过ndk-build生成so文件
- java代码中加载so文件(system.loadlibrary)
- 补充:获取so库的名称
1-libs文件下去头去尾(头:lib;尾:.so);
2-在android.mk直接复制模块名称;
动态注册
- 作用:绑定java方法和C/C++方法的方式之一
- 流程:
- java中定义native的方法
- 创建C++代码代码,导入头文件,编写(配置)两个mk文件:application.mk/android.mk
- JNInativeMethod:绑定java方法和C/C++的方法
- registerNatives(4个参数):注册java层相应的类以及方法
- 使用jni.h中JNI_onload进行判断:注册是否成功(JIN_onload:系统调用,相当于java中的psvm:public static void main)
- ndk-build生成so
- java代码中加载so文件(system.loadlibrary)
静态注册是用到时加载,动态注册一开始就加载好了,这个可以从DVM的源代码看出来。
虚拟机相关的变量中有两个非常重要的量JavaVM和JNIEnv,两者本质上都是指向函数表的二级指针:
- JavaVM:是指进程虚拟机环境,每个进程有且只有一个JavaVM实例
- JNIEnv:是指线程上下文环境,每个线程有且只有一个JNIEnv实例
4 参考文献
[1]丰生强. Android软件安全权威指南[M]. 电子工业出版社, 2019.
[2]https://developer.android.google.cn/training/articles/perf-jni#java
[3]https://blog.csdn.net/xyang81/article/details/41777471
[4]https://cloud.tencent.com/developer/article/1356493
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 xingshuaikun@163.com。