前言:编程世界当中C/C++的的执行效率是其它任何语言不能比拟的,在Android开发中你可能会接触到Android系统中底层算法的使用,而这些算法多数都是用C/C++编写的,如果你想在应用层利用这些算法,通过Java直接调C是不可能的,所以在这类似的需求下,jni由此诞生了,让java和其他语言能进行交流。
1.基础知识简介:
- jni的全称是java Native Interface.它的作用就是让java能够和其他编程语言进行通信(主要是用于C/C++).
-
NDK的全称是Native Development Kit,其实它就是一个帮助工具,帮助打包编译等。
从上到下总共分为三层,Native层提供最原始的C/C++接口代码,接口代码可以直接在JNI中引用。而Java层通过在方法前面添加native关键字,与jni中的方法进行对应(对应的方式有两种:静态注册和动态注册,下一篇将jni语法的时候会说明)。与java对应的jni方法就可以调用native代码了。这就是jni调用的简单流程,就如上图所画的一样.
2.代码演示(no code no bb):
首先我们简单看下工程目录是什么样的:
在这个完成工程中有几个坑,稍后在完成demo的过程中进行填坑.
jni环境配置
*1.在android studio配置一下jni环境,也就是打开File->Project Structure
在SDK Location选项下有个NDK的添加路径。如下图:
紧急提醒:如果你的Android Studio是比较新个版本,添加的NDK是r10*版本的话可能会错误,错误原因就是你的NDK版本过低了,需要在项目的gradle.properties中进行说明
android.useDeprecatedNdk=true
*2.在local.properties中配置上NDK的路径:
*3.最后将NDK的路径在环境变量中进行添加.
开始撸代码:
- 1.创建一个对jni申明的类:
- 2.make一下工程,如果语法上没有错误,你会发现在builde里面会生成一个对应的JniTestMldule.java所对应的JniTestModule.class文件(如下图)。这个文件为我们后面生成jni头文件起决定性作用的.
- 3.为so库生成jni的头文件:
- 在build.gradle中配置编译so库所需要的文件,和最终生成so库的名称
- 编译出so库:直接在android studio的terminal终端执行下图代码
紧急提示:注意我编译时候命令是在那层目录下执行的,如果直接在*.class文件所在目录下执行javah **.class可能会有错。这样可以确保不会出错的.
这里还有一个注意点,上面的工程目录的jni文件夹下,我添加了一个util.c,它里面上面都没有,是一个空文件。为什么要这样做呢?
因为window平台下用ndk编译的时候,jni文件夹下,只有一个.c文件编译是通不过的,所以要加一个空的.c文件。在mac和linux下是没有这种坑爹事情发生的。解决办法是在这里看到的。
http://blog.csdn.net/sodino/article/details/41895211
- 4.上述编译通过后,你在build/intermediates/ndk/debug/lib下面可以看到对应不同平台生成的so
so库都出来了,就可以直接用jni的接口了.