我们知道,Android架构中上层应用是以java来编写的,而底层则用C/C++编写。一般而言,上层android工程师在开发过程中,不会或很少涉及到C/C++层,但项目中一旦涉及到复杂的算法或耗时操作时(例如图像处理等),通常使用C/C++完成算法实现并提供给java层(通过JNI)调用,以此提升软件的运行效率。在这个过程中,C/C++所实现的代码以及JNI调用相关的代码被打包为.so库,这即是所谓的目录设备上的二进制动态库(SHARED LIBRARY),而且.so库更安全,不容易被反编译。那么如何打包自己的.so库呢?
一、在Android studio 中配置NDK
在电脑的环境变量中加入NDK的路径
测试
成功!!!OK。
二、新建一个工程,先做一下配置
1、在app的build.gradl下加入
defaultConfig {
applicationId "jni.svse.com.jnitest2"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk{
moduleName "NDKDEMO" //生成的so名字
ldLibs "log", "z", "m" //链接时使用到的库
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。目前可有可无
}
}
2、在gradle.properties里添加
android.useDeprecatedNdk=true
3、在main下新建一个JNI文件夹
会生成jni文件夹
三、新建调用C/C++的类
public class Load {
static {
System.loadLibrary("NDKDEMO");//NDKDEMO可以随便取,但是必须和moduleName "NDKDEMO" 的名字一样
}
public static native int Add(int a,int b);
}
此时Add会出现红色,不要紧,Alt+Enter,android studio会在jni下自动帮你生成NDKDEMO.c
#include <jni.h>
JNIEXPORT jint JNICALL
Java_jni_svse_com_jnitest2_Load_Add(JNIEnv *env, jclass type, jint a, jint b) {
// TODO在这里编写你的逻辑代码,我这里是相加
return a+b;
}
此时还没有生成.so库
以上2步后会在以下路径生成你的.so库了
生成的类型是根据以下红色来的
ndk{
moduleName "NDKDEMO" //生成的so名字
ldLibs "log", "z", "m" //链接时使用到的库
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。目前可有可无
}
有了自己的.so库怎么使用呢
在新建一个工程,把.so库放到jniLibs下,在工程下新建一个和.so库包名一样的Package,Java_jni_svse_com_jnitest2_Load_Add包名是jni.com.jnitest2,然后再把上面的Load 复制到这里,在Activity里就可以使用了
int value=Load.Add(23, 5);