和前一篇 JNI->JNI唯一不同的就是 编译出.so 需要在Linux 上,然而直接用linux gcc 编译出的.so 是不能被NDK编译的会出 incompatible target 的错误所以需要用到交叉环境 即是 linux下的 ndk编译环境:
我用的是 virtual box 装的 ubuntu 64虚拟机
第一步:制作第一个linux下的动态库来模拟第三方动态库
首先你的linux环境必须装有linux版本的NDK,现在我们来从NDK中分离出独立的工具链,这样我们在制作第三方动态库的时候就不用写makefile了。
在linux命令终端解压压缩包得android-ndk-xx然后再linux终端进入android-ndk-xx的根目录,$ build/tools/make-standalone-toolchain.sh --platform=<PLATFORM> --install-dir=<INSTALL_PATH>按上述格式输入下面的命令
$ build/tools/make-standalone-toolchain.sh --platform=android-14 --install-dir=/home/xx/toolchain/arm-linux-androideabi/
这条命令的意思就是将交叉编译工具完整复制出来,android-14是你的API ,-dir后面是你要复制安装到的目录,执行完后你会发现在/home/xxx/下发现你新建的toolchain目录,到这里我们已经从NDK中分离出独立的工具链了。最后为了方便我们需要设置一下环境变量,如果不设置,每次你都要这样写/home/xx/toolchain/arm-linux-androideabi/bin/arm-linux-androideabi-gcc -c Add.c 这样相当麻烦。
在Linux终端输入 $ sudo -s 获取超级权限,再输$gedit /etc/profile 在弹出的profile文件里将以下内容:export PATH=$PATH:/home/laijingquan/toolchain/arm-linux-androideabi/bin 加到文件的最后一行(这句什么意思?大神可以略去本人下面的赘述。简单说就是设置这个环境变量后,你后面执行arm-linux-androideabi-gcc这个命令时就会自动在:/home/laijingquan/toolchain/arm-linux-androideabi/bin这个目录里去寻找。)接着再执行 $ source /etc/profile 让环境变量立即生效。
arm-linux-androideabi-gcc -c xxxx.cpp 生成.o的文件
arm-linux-androideabi-gcc -shared -fPCI -o libxxxx.so xxxx.o 生成动态链接库.so文件
第二部:
将生成的.so 文件 拷贝到 工程目录 jni下,在jni下新建 include文件夹将.h文件拷贝进去。
在 原始的C 语言.h文件里面加上3行代码:
第一行加 include<jni.h> 在所有include 最下边加上 extern "C" { 就是包含你所有的接口名,将接口名最前面加上JNIEXPORT,中间加上 JNICALL ,就变成了这个摸样就行了: JNIEXPORT void JNICALL neuglClearColor(float r, float g, float b, float alpha); }
还需要在 加载本地JNI库的地方加载下:
public class NativeInterface { public native static int init_view(); public native static int draw_view(); public native static void neuglClearColor(float r,float g,float b,float alpha); static{ System.out.println("java start load MyTestLib.so...."); System.loadLibrary("MyTestLib"); System.out.println(System.mapLibraryName("MyTestLib")); System.out.println("java loaded MyTestLib.so"); System.out.println("java start load Jtestc.so...."); System.loadLibrary("Jtestc"); System.out.println("java loaded Jtestc.so"); } }
最后贴上 .mk文件代码:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := MyTestLib LOCAL_SRC_FILES := eslib/libMyTestLib.so LOCAL_C_INCLUDES := eslib/include include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := Jtestc LOCAL_SRC_FILES := Jtestc.cpp LOCAL_LDLIBS := -lGLESv2 LOCAL_LDLIBS += -llog -lz -lm LOCAL_SHARED_LIBRARIES := MyTestLib include $(BUILD_SHARED_LIBRARY)