在上一篇文章中搭建好了Eclipse下NDK环境,现在开始NDK的开发:
1、打开Eclipse,新建一个Android Project,名字就叫HelloNdk,package:org.android.code
2、然后在org.android.code 包里新建一个helloNdk的Class。.
在该类中声明本地调用的方法,如下图:
然后将项目编译一下,让Eclipse生成helloNdk的class文件,用于生成.h文件。
3、生成.h文件
启动cmd,进入项目的bin\class目录下,输入javah+空格+包名.类名。
4、编写C/C++代码
在项目中新建一个jni文件夹,把class目录下的org_android_code_helloNdk.h文件move到该文件夹下,刷新HelloNdk项目。
打开jni文件夹下的org_android_code_helloNdk.h文件。修改为helloNdk.h,方便操作。如图:
Java_org_android_code_helloNdk_add和Java_org_android_code_helloNdk_outputFromNdk就是我们要在C/C++中实现的方法。
5、 新建一个文件,命名与.h文件保持一致,扩展名为.c。
可以看出,C/C++文件中类的命名方式为Java_包名_类名_方法名,只是用_替换了原Java类的.符号。
说明:
jint表示返回类型为java的int类型; jstring表示返回类型为java的String类型;函数名由Java_调用函数的包名_类名_方法名。
env代表java虚拟机环境,Java传过来的参数和c有很大的不同,需要调用JVM提供的接口来转换成C类型的,就是通过调用env方法来完成转换的。
this代表调用的对象,相当于c++的this。当c函数需要改变调用对象成员变量时,可以通过操作这个对象来完成。
本例比较简单,不需要用到这两个参数。但是这两个参数在JNI中非常重要。
6、在HelloNdkActivity中调用Jni方法,HelloNdkActivity的内容如下:
7、编译C/C++,生成.so文件:
1) 在jni目录下新建或从其它项目中拷贝一个Android.mk文件,文件内容如下:
文件内容如下:
说明:
LOCAL_PATH := $(call my-dir)
一个Android.mk 文件首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含
Android.mk file文件的目录)。
include $( CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES,
等等...),但第1行定义的LOCAL_PATH不在清空的范围内。因为所有的脚本都将粘贴到同一个GNU Make的执行上下文中,而且所有变量都是全局变量,因此必须在每次使用
前清空所有以前用过的变量
LOCAL_MODULE := helloNdk
编译的目标对象,LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包含任何空格。
注意:编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'hello-jni'的共享库模块,将会生成'libtest-jni.so'文件。
重要注意事项:
如果你把库命名为‘libhelloNdk’,编译系统将不会添加任何的lib前缀,也会生成 'libhelloNdk.so',这是为了支持来源于Android平台的源代码的Android.mk文件,
如果你确实需要这么做的话。
LOCAL_SRC_FILES := helloNdk.c
LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的
文件;仅仅列出直接传递给编译器的源代码文件就好。
注意:默认的C++源码文件的扩展名是’.cpp’. 指定一个不同的扩展名也是可能的,只要定义LOCAL_DEFAULT_CPP_EXTENSION变量,
不要忘记开始的小圆点(也就是’.cxx’,而不是’cxx’)
include $(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY表示编译生成共享库,是编译系统提供的变量,指向一个GNU Makefile脚本,负责收集自从上次调用'include $(CLEAR_VARS)'以来,定义
在LOCAL_XXX变量中的所有信息,并且决定编译什么,如何正确地去做。还有 BUILD_STATIC_LIBRARY变量表示生成静态库:lib$(LOCAL_MODULE).a,
BUILD_EXECUTABLE 表示生成可执行文件。
2)配置项目的Builder:单击项目属性,选择Builders,New,Program。关于详细的配置,上一篇有介绍,此处就不再赘述。
3)Build your project。编译成功,会在Console控制台输出相应的信息:
8、运行,Run As。结果如图: