对Android应于用开发,大部分情况下我们使用Java就能完整地实现一个应用。但是在某些情况下,我们需要借助C/c++来写JNI本地代码,比如,在使用跨平台的第三方库的时候,为了提升密集计算性能的时候(这种情况下往往还可能会直接使用汇编语言),因此,这里我将为大家介绍如何给其它开发者创建可供使用的静态库或动态库。而应用开发者如何去连接这些生成的静态库或动态库。由于现在Android工作室已经比较成熟,因此以下描述将基于Android工作室的目录布局。
在Android工作室的一个项目工程下,会有一个应用程序文件夹,这个文件夹主要存放我们编写应用的所有代码以及相关其它资源。如果我们需要写JNI,那么就需要在这个目录下创建JNI文件夹.jni文件夹里必须包含Android.mk文件,Application.mk文件以及你所要编译的源文件。下面我们先给出编译生成提供给第三方开发者使用的静态库与动态库的Android.mk文件内容:
LOCAL_PATH:=$(调用my-dir) 包括美元(CLEAR_VARS) #编译后生成的模块名,在Java端使用System.loadLibrary加载模块的的时候直接用此名 LOCAL_MODULE:=my_blocks # LOCAL_SRC_FILES用于添加源文件(可以是c, . cpp、s等) LOCAL_SRC_FILES:=my_block_test.c LOCAL_SRC_FILES +=my_blocks_data.c LOCAL_SRC_FILES +=my_runtime.c #条件预编译,如果当前架构为v7以下的架构,则定义MY_NO_CSWAP这个宏 ifeq ($ (TARGET_ARCH_ABI) armeabi) LOCAL_CFLAGS:=-DMY_NO_CSWAP=1 endif #连接系统编译出的静态库 LOCAL_STATIC_LIBRARIES:=cpufeatures LOCAL_STATIC_LIBRARIES +=ld.gold LOCAL_LDLIBS:=-llog #用于生成动态库 # include $ (BUILD_SHARED_LIBRARY) #用于生成静态库 包括美元(BUILD_STATIC_LIBRARY) $(叫import-module, cpufeatures)
然后,我们把上述编译脚本中所列出的my_block_test.c, my_blocks_data.c以及my_runtime.c这三个源文件放在jni目录下即可编译。
最后,用Android JNI编译器工具,ndk_build编译完之后就可在生成的obj目录下看到my_blocks.a文件了,在Unix/Linux下。表示静态库文件,所以表示动态共享库文件。
下面我们将创建另一个工程,这个工程将构建最终可执行的应用。其Android.mk文件描述如下:
LOCAL_PATH:=$(调用my-dir) # # #以下这段用于预构建我们将要连接的已存在的静态库或动态库# # # 包括美元(CLEAR_VARS) #我们将连接已编译好的my_blocks模块 LOCAL_MODULE:=my_blocks #填写源文件名的时候,要把静态库或动态库的文件名填写完整。 # $ (TARGET_ARCH_ABI)/表示将不同架构下的库文件存放到相应架构目录下 LOCAL_SRC_FILES:=(TARGET_ARCH_ABI)/libmy_blocks.a美元 # LOCAL_SRC_FILES:=(TARGET_ARCH_ABI)/libmy_blocks.so美元 #用于预构建静态库(后面可被连接) 包括美元(PREBUILT_STATIC_LIBRARY) #用于预构建动态库(后面可被连接) # include $ (PREBUILT_SHARED_LIBRARY) #这里要注意的是,对于一次预构建只能预构建动态库,要么是静态库,两者不能共存 # # #以下内容用于描述编译当前工程的源代码# # # 包括美元(CLEAR_VARS) LOCAL_MODULE:=mytest LOCAL_SRC_FILES:=test.c LOCAL_STATIC_LIBRARIES:=cpufeatures LOCAL_STATIC_LIBRARIES +=ld.gold #连接我们前面声明好的静态库 LOCAL_STATIC_LIBRARIES +=my_blocks #连接我们前面声明好的动态库 # LOCAL_SHARED_LIBRARIES +=my_blocks LOCAL_LDLIBS:=-llog #将此模块构建为动态库 包括美元(BUILD_SHARED_LIBRARY) $(叫import-module, cpufeatures)
下面我们来看一下这个工程jni的目录结构内容:
在arm64-v8a, armeabi等每个架构名目录下,都要包含有我们在第一个工程中生成出来的静态库或动态库文件,并且要与架构名相一致。比如一下是arm64-v8a下的内容: