android机制中,java代码的运行须依托于java虚拟机,效率是比较低的,最近做高效大数乘法中,发现使用NDK可以实现C与Java混编(能引用c的动态库,本次项目成功引用了gmp库),而且android中的C语言不需要依托java虚拟机,效率还是非常高的。
一、开发环境的搭建
要实现c与java混编,需根据自己的系统类型,额外下载 android-ndk-r9d,linux系统安装命令如下方法:
$ cd android-ndk-r9d/ $ build/tools/make-standalone-toolchain.sh --toolchain=arm-linux-androideabi-4.8 --platform=android-19 --system=linux-x86_64 --install-dir=$HOME/android-19-arm同时 要为其添加环境变量,以便直接使用。具体步骤这儿不赘述了。
二、开发过程
整个过程总体流程是:
在java中声明与C的接口函数 -> javah命令导出.h的头文件 -> 编写c程序
-> 编写Android.mk -> 使用ndk-build编译C程序为动态库文件 -> android编译
1、java中声明C接口函数
public class func { static{ System.loadLibrary("cfunc"); // 预引用库(前不写lib后不写.so) } private native String jni_say(); // 声明C程序中的接口函数 }
2、导出.h头文件
利用终端进入工程目录,进入 /bin/classes
使用javah + 包名 + 类名 导出头文件
会看到当前目录下多了一个.h文件
3.编写c程序
首先在工程根目录下建一个名为“jni”的文件夹,将上步生成的.h文件复制过来,根据.h编写.c/.cpp即可
在接口中可以引用其他写好的c/c++函数/文件,需注意接口中的与java交互的数据类型与c/c++不一样,需另外学习下,其他的就一模一样了。
可参考:http://blog.sina.com.cn/s/blog_5de73d0b0101chk1.html
4.编写Android.mk
Android.mk作用类似Makefile文件,保存的是编译信息。
此处没有引用其它的.c/.cpp/库文件,如有引用的话,需修改Android.mk的代码,使其重新编译新的动态库。例如,如果接口对应了.cpp中引用了a.h,a.h中函数的实现存在a.cpp中。只需在Android.mk的 LOCAL_SRC_FILES 末尾添加”/a.cpp“即可。
详情可参考 http://www.2cto.com/kf/201310/253386.html
5、使用ndk-build将c代码编译成动态库
直接在jni目录下使用ndk-build命令即可
这时,F5刷新一下,就能发现在android工程目录下的libs中会多一个armeabi文件夹,里面就是生成的动态库。
6、编写测试程序,Android端编译工程,运行调试
注意,jni项目只能采用真机测试,模拟器是跑不了的。
三、引用C语言库
代码写法与c语言相同,主要还是修改Android.mk来实现编译。具体参照上面提供的网址。
其它可参考资料:
http://zzbupt.iteye.com/blog/1876496nd
ndk-build的用法:http://blog.csdn.net/smfwuxiao/article/details/8523087