Android开发中,java与其它语言(如C、C++)进行交互可以通过JNI(Java Native Interface)的方式。这种方式大概是这样来实现:1、java中声明并调用native方法;2、本地实现上层调用的方法,并以动态库的方式提供上层调用。工作中遇到了这种情况:需要完成一个Android设备的本地porting接口测试,且该网关设备没有视频输出接口。由于无法输出测试界面,那么通过测试APK调用本地接口的方法(如上所述)便不合时宜了。需要实现一个控制台程序,完成对本地接口的测试。那么,通过C来实现一个控制台测试程序是非常简单的,需要做的就是建立这样一个项目工程。下面将主要讲一下这个工程的建立。
我们首先需要找到对应版本的NDK(Native Development Kit)。NDK是Android提供的供本地代码开发的一系列工具(编译器、Android运行时库等)。在使用JNI方式的时候,也需要使用到NDK,此时NDK的作用就是产生那个本地动态库供java调用。
接下来我们就可以开始进行交叉编译工程的构建了,下面给出一个例子,目标机为mipsel架构。如下所示,在脚本文件setenv.sh定义需要使用的编译器及编译选项:
/setenv.sh/
CMP_PATH="/mnt/hgfs/Develop/android_ndk/gcc/linux-x86/mips/mipsel-linux-android-4.6/bin"
NDK="/mnt/hgfs/Develop/android_ndk/android-14/arch-mips"
exportCC=$CMP_PATH/mipsel-linux-android-gcc
exportCFLAGS="-I$NDK/usr/include -I$SOURCE_PATH/include"
export LDFLAGS="-nostdlib-Wl,-rpath-link=$NDK/usr/lib -L$NDK/usr/lib $NDK/usr/lib/crtbegin_dynamic.o-lc"
上面的编译选项中需要注意的是,-nostdlib指不使用宿主机的库文件,而使用NDK提供给我们的库文件,同时我们还定义了所使用的运行库crtbegin_dynamic.o。
在定义了环境变量之后,再构建Makefile即可。我在NDK中找了一下,未找到make工具。想来也是,NDK并不是用来实现一个工程而设计的。我们使用本地宿主机的make工具即可,具体的make脚本编写可查找相关资料,此处提供一个例子。
/*Makefile*/
OBJS =test_case_osp.o \
main.o
lib:$(OBJS)
$(OBJS):%.o:%.c
$(CC) -c $(CFLAGS) $(LDFLAGS) $< -o $@
all:
$(CC) -o test $(OBJS) $(LDFLAGS) -ldl -lm
clean:
-rm *.o
完成工程的构建之后,完成代码编写,./setenv.sh设置环境变量,make编译连接可执行文件test。将test拷贝到Android系统下,将权限设置为可执行,./test即可执行该程序。