0x01 JNI介绍
JNI是Java Native Interface的缩写,JNI不是Android专有的东西,它是从Java继承而来,但是在Android中,JNI的作用和重要性大大增强。
JNI在Android中起着连接Java和C/C++层的作用,现在APP的许多重要的逻辑,算法以及和底层的交互功能都是通过JNI调用C/C++来实现。
简单来说,JNI提供了一种可以让Java代码调用C/C++代码的接口。
0x02 JNI中的类型/数据结构
JNI的类型/数据结构,以及函数的声明都放在jni.h的头文件中,这个头文件可以在NDK的platforms文件夹下android对应版本的对应架构文件夹下找到。比如
platforms\android-21\arch-arm64\usr\include\jni.h
一些比较重要的类型如下:
1. 基本类型(都是一些C类型的重命名)
2. 常见的对象类型
jobject 代表Java中的对象
jstring 代表Java中的String类型
jclass 代表Java中的类
jobjectArray/jbooleanArray 等都是数组类型
3. JNIEnv代表JNI环境的结构体
可以看到JNIEnv结构体中有大量函数指针,我们可以通过这个结构体来调用jni.h中声明的函数,之后会有代码来说明这结构体的作用
0x03 Native函数的静态注册与动态注册
前面的数据类型比较无聊,其实我们主要关注的还是Java native函数是怎么和C/C++关联起来的,关联起来后,C/C++函数的编写和正常的C/C++代码基本相同。
Native函数的注册有两种方式:静态注册和动态注册。
关于使用Android Studio编写Native代码的相关配置可以参考:
http://tools.android.com/tech-docs/new-build-system/gradle-experimental
1. 静态注册
静态注册较为简单,所以先来用一个例子来说明一下静态注册。
使用AndroidStdio新建项目,我们把项目命名为HelloNative
在项目中新建一个文件夹jni
在MainActiviy中声明两个native属性函数,第一个函数为static, AS提供alt+enter快捷键可以新建mainactivity并快速生成这两个函数对应的Native层函数框架
在MainActivity开始处加载so库
mainactivity.c:
mainactiviy.c中的函数就是我们要编写的native函数
Java_dlive_hellonative_MainActivity_Hello1对应Java中声明的Hello1函数
Java_dlive_hellonative_MainActivity_Hello2对应Java中声明的Hello2函数
这就是静态注册,即Native函数的函数名由Hello1的packagename和Hello1的函数名组成,Java层调用Hello1时,会调用mainactivity.so中对应的
Java_dlive_hellonative_MainActivity_Hello1函数。
这里还有几点要注意:
1. Java层函数对应的Native层函数的第一个参数为JNIEnv*
2. 被声明为static的函数Hello1对应的Native函数
Java_dlive_hellonative_MainActivity_Hello1 第二个参数为jclass,表示Hello1函数所在的类
3. 没有static声明的函数对应的Native函数的第二个参数为jobject,表示调用Hello2的对象
4. Native函数从第三个参数开始才对应Java层函数的参数
2. 动态注册
动态注册与静态注册的区别在于Native的函数名可以自定义,然后使用JNI提供的
RegisterNatives动态将Java层函数和Native层函数绑定起来即可。
动态注册主要依赖两个函数JNI_OnLoad和RegisterNatives
JNI_Onload会在so加载的时候自动被调用,在JNI_Onload中调用RegisterNatives将Java层函数和Native层函数关联起来。
MainActivity.java中native属性的函数:
在jni目录下新建hello.cpp和hello.h,在hello.cpp中实现native函数
可以看到实现的函数名称为helloNative,而不是静态注册时很长的函数名。
gClassName : Java层类名
gMethods:{java层函数名,java层函数签名【(参数)返回值】,native层函数指针}
registerNativeMethods是找了一个网上的实现,就是封装了一下RegisterNatives
0x04 JNI中提供的函数
JNI中提供了哪些函数可以在jni.h中找到,这里只讲一下常用的几个函数。
讲解顺序是按照jni.h中声明的顺序排序的。
注:本博客文章转载需带上原文链接