上一篇android studio 3.2 使用jni(cmake的方式)
下一篇android studio 3.2 使用cmake在jni生成及使用C/C++静态库
总体思路:
- 新建一个my.cpp和my.h文件
- 利用android studio中的cmake工具将my.cpp编译成全架构(armeabi-v7a,arm64-v8a,x86,x86_64)的库文件。编译时很多问题,报错时出现x86或者armeabi都是因为没有对应的架构造成的,我们索性就直接造一个全架构的库。
- 将第2步中生成的库链接到native-lib.so(系统自动生成的库)中
- 运行,看在native-lib.cpp中的函数能否调用my.cpp中的函数
我们从头开始,最好新建立一个文件。
1.建立jni文件
不多说,看android studio 3.2 使用jni(cmake的方式)
建立好之后先运行app,看能否运行,不能运行就先百度解决,正常运行之后再进行后面的操作
2.新建my.cpp和my.h
1.在Project视图下 app/src/main/cpp 目录下创建my.cpp同时创建头文件my.h
2.在my.cpp写一个函数,并且添加android的日志库,以便知道当前函数是否被正确被调用
my.h如下:
#ifndef JNITEST2_MY_H
#define JNITEST2_MY_H
//-----------------------------横线里面的内容为新增--------------------------
#include <android/log.h>
#define LOG "JNILOG"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG,__VA_ARGS__)
int my_fun();
//-------------------------------------------------------------------------
#endif //JNITEST2_MY_H
my.cpp
#include "my.h"
//-----------------------------横线里面的内容为新增--------------------------
int my_fun()
{
LOGD("android studio jni");
return 111;
}
//-------------------------------------------------------------------------
3.将my.cpp编译成全架构的.so库
1.修改CMakeLists.txt,只新增了两句,原来的不需要改
cmake_minimum_required(VERSION 3.4.1)
add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
#-----新增--------
add_library(my-lib SHARED src/main/cpp/my.cpp)
find_library(log-lib log)
target_link_libraries(native-lib ${log-lib})
#-----新增---------------
target_link_libraries(my-lib ${log-lib})
2.修改app级别下的build.gradle新增一句
3.点击make project
4.编译成功之后,查看生成的库
在Project目录下 app/build/intermediates/cmake/debug/obj/各种架构
libmy-lib.so就是我们需要链接到libnative-lib.so的库
4.将libmy-lib.so链接到native-lib.so
1.修改CMakeLists.txt文件
cmake_minimum_required(VERSION 3.4.1)
add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
#-----删除--------
#add_library(my-lib SHARED src/main/cpp/my.cpp)
#-----新增---------
add_library(apple SHARED IMPORTED)
#-----新增---------
set_target_properties(apple PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/build/intermediates/cmake/debug/obj/${CMAKE_ANDROID_ARCH_ABI}/libmy-lib.so
)
find_library(log-lib log)
#------修改---------
target_link_libraries(native-lib apple ${log-lib})
#-----删除---------------
#target_link_libraries(my-lib ${log-lib})
#删除的就表示不要了,#新增就表示新添加的,#修改就表示在原来的基础上修改
说明一下set_target_properties这里面的参数。
${CMAKE_CURRENT_SOURCE_DIR} 表示app这个文件夹,也可以用别的参数来表示。因为Android studio的版本不同,参数可能回不一样,但是一定要能定位到cmake/debug/obj这个文件夹。可以用ctrl+左键来试一下能否被识别。
${CMAKE_ANDROID_ARCH_ABI}表示系统会根据自己的要求去不同的架构目录下去寻找libmy-lib.so,所以不要指定单独的文件夹
2.在native-lib.cpp中调用我们my.cpp的函数
#include <jni.h>
#include <string>
//---------新增
#include "my.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_tuweiguang_jnitest2_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
//-----------新增-------------
int x = 0;
x = my_fun();
LOGD("x = %s",x);
//---------------------------
return env->NewStringUTF(hello.c_str());
}
5.运行app
点击运行app
成功调用
下载DEMO