前言:JNI(Java Native Interface)是Java本地接口,我们知道,Android 上层开发基本都是Java,而底层开发使用的是c或c++语言,那么他们是如何通信的呢?答案是JNI,其实jni就像java与c/c++通信的桥梁。今天的任务就是讲一下利用Android studio进行jni的基本流程。
准备:我们需要用到NDK开发包,虽然android studio已经集成的ndk,但是这边使用起来好像有点问题,网上很多例子都是使用android-ndk-10e版本的,所以我这边用的android-ndk-10e开发包;
1、新建一个android 项目-->新建一个util包-->在util下新建一个JniUtil.java文件,在文件中新建一个native方法,注意:本地方法必须用native声明,如下所示:
2、make project一下,在\app\build\intermediates\classes\debug\com\richard\demo\util目录下就会生成一个JniUltil.class文件,然后打开命令行,进入到\app\build\intermediates\classes\debug目录下,执行命令 javah -jni com.richard.demo.util.JniUtil 就会在当前目录生成一个java_com_richard_demo_util_JniUtil.h文件,如下所示:
ps:如果你自己编译class文件也可以,命令行进入到类名所在的目录,然后执行命令:javac JniUtil.java,如果报编码格式错误,那么就需要指定编码格式:javac -encoding UTF-8 JniUltils.java,便可以在当前目录生成JniUtils.class文件,执行javah命令前需要退到java目录下,然后执行命令:javah -jni com.richard.demo.utils.JniUtil 便可在java目录下生成JniUtil.h文件。
如果native 方法存在参数且是android类,那么编译的时候或者编译成头文件的时候可能会提示找不到android.xxx类,这是需要将项目中引入android.jar的路径配置到环境变量classpath中:因为前面路径遮住了,所以用文字打出,如下所示
3、在java同级目录新建一个jni文件夹,然后将java_com_richard_demo_util_JniUtil.h拷贝到jni下面,然后再新建一个JniUtil.c的源文件,将java_com_richard_demo_util_JniUtil.h中的内容拷贝到JniUtil.c中,因为h文件是一个头文件,只是JNI方法的签名,签名格式:java_包名_类名_方法名,c文件才是真正对其方法的实现;
4、在local.properties文件中配置ndk路径,如下所示,你的写你自己ndk路径:
5、在gradle.properties文件中加上这句代码:
6、在app的build.gradle中配置如下代码:
7、在jni下新建Android.mk文件配置如下脚本:
LOCAL_PATH: 指定Android.mk位置
LOCAL_MODULE : 生成so的名称
LOCAL_SRC_FILES : 指定编译的源文件
include $(BUILD_SHARED_LIBRARY) : 指定生成so库,如果想生成.a文件指定include $(BUILD_STATIC_LIBRARY);
8、ReBuild一下,就会在app/buidl/intermediates/ndk/debug/lib下生成armeabi和armeabi-v7a的so文件
9、在java同级目录新建一个jniLibs目录,将so文件拷贝到下面,然后在调用so的地方引入so文件,进行调用:
大功告成,jni一个最基本的开发流程就实现了。