使用cmake进行Android项目的构建
cmake编辑功能是android studio 2.2才支持的新功能;目的是简化jni的开发过程,使用studio2.2新建项目的话,会有相应的让你勾选使用cmake。如图:
当勾选了include C++ Support时,在创建项目的时候,会多出如上界面,选择C/C++的标准,此处的设置在app的build.gradle中的defaultConfig会增加如下设置:
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"//这个标记是第一个选项,如果使用C++11的标准,则使用:
// cppFlags "-std=c++11"
//也可以一起使用:
// cppFlags "-std=c++11 -frtti -fexceptions"
}
}
上述位置,还可以设置动态库的平台支持,如:
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'//平台支持,生成对应so
}
}
在build.gradle中的android节点下面会增加配置,指定生成so文件配置文件的路径:
externalNativeBuild {
cmake {
path "CMakeLists.txt"//该路径为相对位置,相对于当前build.gradle位置
}
}
项目最终目录结构:
实现java中native使用类:
public class NativeUtil {
static {
System.loadLibrary("native-lib");
}
//调用的时候就这么调就好了,这就是在native-lib里的函数
public static native int maxFromJNI(int a, int b);
}
通过javah命令,生成对应头文件:
执行build操作,或者run操作,会在如下目录中进行java类编译,生成对应class文件,我们可以通过class文件来执行javah操作,进而获取native类对应头文件,目录如图:
通过cmd命令窗口,cd当前app目录,如上图。然后执行javah命令,生成头文件。
javah命令如下:其中“jni”表示生成 JNI 样式的标头文件;“-classpath”表示从中加载类的路径;“.”表示当前目录,即类加载路径为当前目录;“-d”表示输出目录,即表示输出到c/c++工程目录cpp中;“com.opengles.home.NativeUtil”表示对应的加载类的绝对索引。
javah -jni -classpath ./build/intermediates/classes/debug -d ./src/main/cpp com.opengles.home.NativeUtil
也可以通过在Android Studio中配置External Tools进行javah命令实现,更便捷。配置添加,如图:
具体配置,如图:
操作方式,如图:
执行过程,目录如下:
实现Max.cpp:
int max(int a, int b) {
return a > b ? a : b;
}
实现Max.h:
#ifndef GLHOME_MAX_H
#define GLHOME_MAX_H
int max(int a, int b);
#endif //GLHOME_MAX_H
实现native-lib.cpp:
#include <jni.h>
#include "Max.h"
#include "com_opengles_home_NativeUtil.h"
JNIEXPORT jint JNICALL Java_com_opengles_home_NativeUtil_maxFromJNI
(JNIEnv * env, jclass cls, jint a, jint b){
return max(a,b);
}
在run成功之后,会在build目录的上方增加.externalNativeBuild目录,其中.externalNativeBuild/cmake/debug/obj包含所有生成的so包,同样的拷贝到其他项目中的jniLibs对应目录中就可以直接的使用,自主项目无需拷贝。
第三方工程使用,需要指定jniLibs目录,方法如下图:
该目录,即libs目录,是同一个,如图: