最近几天看了有关android NDK方面的开发博客,相对此对一下总结:
实验平台:
操作系统:win7
开发环境:Eclipse+ADT+AVD+JDK1.6+Cygwin+android NDK1.6_r1
android开发环境的搭建,可以参考[1].android NDK环境搭建可以参考[2].
注:
1.JDK1.6安装的时候,没有发现问题,用Eclipse很久了,也没有发现什么问题,正常使用。
当在命令行cmd.exe中运行java时也正常,运行javac和javah时,出现问题。后来发现,原来是jdk的lib目录下缺少tools.jar工具包。下载后才解决问题。
2.Cygwin的安装:有些教程为了省事,在安装Cygwin的时候,让你选择安装所有的包,结果10G的硬盘空间都不够。其实,我们用不到这么多的包,只需要gcc和make相关的12个包就行了。(autoconf2.1、automake1.10、binutils、gcc-core、gcc- g++、gcc4-core、gcc4-g++、gdb、pcre、pcre-devel、gawk、make)
NDK编写流程:
1.编写java代码,在其中声明native函数,也即是我们要用c/c++实现的函数。
2.用javah将生产的.class文件编译成.h文件,即native函数对应的头文件
3.用c++编辑器或记事本,编写实现c/c++的代码
4.使用Cygwin工具,用android NDK工具编译第2,3步中的c/c++文件。编译成.so库文件
5.复制.so文件到工程目录(lib)
6.在java中,载入.so库。即可使用natvie声明的函数。
注意事项:
配置:我用的NDK是android NDK1.6_r1,不是最新的。不同版本之间有差别!新手还是先用1.6的,等熟练之后用最新的。在Cygwin的home\[你的用户名]\.bash_profile中加入NDK的路径,并导出NDKROOT变量。
NDKROOT=/cygdrive/[你的NDK路径]/android-ndk-1.6_r1 export NDKROOT
可以用make APP=hello-jni命令,编辑NDK自带的项目。测试一下是否安装正确了。
第一步:声明的方式为public native void write();
第二步:编译时用javah命令,Eclipse已经在工程目录的bin/classes/[包名]/生成了class文件。我们就要用javah编译声明有native方法的class文件
注意,要将工作路径切换到工程目录的bin/classes/。在编译时要加上包名,javah [包名].[类名]。尽量将整个项目拷贝到NDK的apps目录下。
第三步:以第二步生产的.h文件,编写c/c++文件,在工程目录下新建jni文件夹,将c/c++源文件拷贝过去。注意:产生函数的参数!我编辑之后,函数参数竟然为:(JNIEnv *, jobject),只有参数类型没有参数变量!导致第四步出错。还好,参考了一下hello-jni中的例子,改为了(JNIEnv *env, jobject thiz)
第四步:编译之前要写2个.mk格式的文件。
一个是Application.mk。这个文件放在工程(要编译的工程)目录下,内容为:
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES := MyJNItest
第一句是你的项目的路径,$(call my-dir)是获得Application.mk的路径。我们的项目就是和Application在同一个目录下。因此,上述配置就可以。
但是也有人发现了,在hello-jni中,他们配置的是
APP_PROJECT_PATH := $(call my-dir)/project
这是因为,他们的项目在project文件夹里,而他们的Application.mk和project文件夹在同一级里面APP_MODULES指的是Application.mk所在的文件夹。
第二个.mk文件时Android.mk文件,将它与源文件放在一起,都在第二步中jni文件夹下,内容如下:
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:=MyJNItest
LOCAL_SRC_FILES:=com_example_testjni_JNIClass.c
include $(BUILD_SHARED_LIBRARY)
第一句话是写明c/c++文件的路径
第二句话是清空
第三句话是项目的名称
第四句话是源文件的名称
第五句话是指编辑成共享的库(.so)
将Cygwin切换到NDK的目录下;输入命令:
make APP=MyJNItest
MyJNItest即是Application.mk和Android.mk中的MOBULE的值。一般都是指工程名。
第五步:如果你是将整个项目都拷贝到了NDK目录下,那么.so库文件已经在libs的armeabi文件夹下。
第六步:定义一个static块,载入库文件System.loadLibrary("库名");注意,.so库必须以lib开头,如果生成的库名为libMyJNItest.so那么,载入时只能这样写:System.loadLibrary("MyJNItest");lib和.so都不能带。
项目源码:http://download.csdn.net/detail/nuptboyzhb/4555207
转载请声明:http://blog.csdn.net/nuptboyzhb/article/details/7955838
参考:
[1]android开发平台搭建:http://wenku.baidu.com/view/2b2aa341b307e87101f6960a.html
[2]android NDK环境搭建:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/13/2136982.html
[3]android NDK入门:http://www.oschina.net/question/195301_31710