2.2以后默认使用cmake,创建项目时记得选择支持c++,会在app目录下自动生成CMakeLists.txt,以及在cpp下生成native-lib.cpp
先看看默认的cpp文件的内容
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_groot_cmaketest3_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
在MainActivity中声明native函数即可调用
public native String stringFromJNI();
这里可以看出,jni调用,cpp中定义的函数名需要遵循一定的格式:Java+包名+调用类名+函数名
有时候,我们可能需要调用第三方so库,那么我们先自己生成一个so库,然后再自己调用
在cpp目录下创建Add.cpp和Add.h文件,内容分别如下
#ifndef CMAKETEST3_ADD_H
#define CMAKETEST3_ADD_H
#endif //CMAKETEST3_ADD_H
class Add{
public:
Add();
~Add();
int add(int a, int b);
};
#include "Add.h"
Add::Add() {}
Add::~Add() {}
int Add::add(int a, int b) {
return a+b;
}
修改Cmakelist内容如下
cmake_minimum_required(VERSION 3.4.1)
#设置变量jnilibs,CMAKE_SOURCE_DIR是内置变量,指向cmake文件所在的目录
set(jnilibs "${CMAKE_SOURCE_DIR}/src/main/jniLibs")
#设置so库生成的目录,ANDROID_ABI指不同的cpu版本
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${jnilibs}/${ANDROID_ABI})
#生成库的名字是add,类型是SHARED,也就是.so库,STATIC是.a库,这里cpp路径可以使用相对路径
add_library(add SHARED src/main/cpp/Add.cpp)
然后运行程序,会在jniLibs目录下生成各版本对应的so文件
接下来新建一个工程,同样选中支持c++,将生成的so文件以及头文件拷贝过去,大致结构如下
修改cmake文件如下
cmake_minimum_required(VERSION 3.4.1)
#指明要引用的头文件的地址
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp)
#配置native-lib.cpp生成的so文件名称
add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
#配置要引用的其他so库,IMPORTED表示引用
add_library(add SHARED IMPORTED)
#上一步说明要引用,这一步就要设置路径,记住只能是绝对路径,否则可能出错
set_target_properties(add PROPERTIES IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libadd.so")
#链接这些so库
target_link_libraries(native-lib add)
修改native-cpp如下
#include <jni.h>
#include <string>
#include "Add.h"
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_groot_cmaketest2_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
Add add;
return add.add(1,3);
}
最后在mainactivity中调用,大功告成,不过在写的过程中遇到过这个错误missing and no known rule to make it cmake,造成的原因有两点,如下:
1、cmake中引用的第三方so库没有指明绝对路径,或路径有误
2、没有将所有对应cpu的so库拷贝过来
代码 出于大小的考虑,已经将jniLibs下的so删除,需要自己生成后才能正常运行