目标是 java 层通过 jni 调用拿到一个 cpp 层返回的 string。
开始。
第零步,配置好 ndk 等
去官方下载 ndk,目前最新版是 r21b;然后放到合适位置;
回到 Androidstudio,打开 local.properties 文件,加上 ndk 的路径;
ndk.dir=/Users/xxx/Library/android-ndk-r21b
sdk.dir=/Users/xxx/Library/Android/sdk
第一步,先建一个 cpp 目录,在 java 的同级目录下
- /app/src/main/java(这下面是java文件)
- /app/src/main/cpp(在这下面建cpp文件)
// 新建 native_test.cpp 文件
#include <jni.h>
#include <string>
// 需要绑定一个 java 类
#define JNI_CLASS_PATH "com/anything/sample/CppActivity"
extern "C" JNIEXPORT jstring JNICALL
//Java + 包名 + 类名 + 函数名
Java_com_anything_sample_CppActivity_stringFromJNI(
JNIEnv *env,
jobject ) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
注意函数名要和调用的Java类格式对上。
第二步,编写 cmake 脚本文件
- /app 路径下,新建 CMakeLists.txt 文件
cmake_minimum_required(VERSION 3.4.1)
# 引入cpp源文件
add_library(
native-lib # so 名
SHARED
src/main/cpp/native_test.cpp)
# 引入系统库
find_library(
log-lib # 别名
log) # 原生的ndk的log库
# 链接起来
target_link_libraries(
native-lib
${log-lib})
第三步,build_gradle 中引入 cmake
- 在 app 模块的 build_gradle 中的 android 块下,增加:
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
- 然后在 android 块中的 defaultConfig 块下,增加参数配置:
externalNativeBuild {
cmake {
cppFlags ""
}
}
第四步,调用
public class MainActivity extends AppCompatActivity {
// 加载
static {
System.loadLibrary("native-lib");
}
// 声明
public native String stringFromJNI();
// 调用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.sample_text);
String hello = stringFromJNI();
tv.setText(hello);
}
第五步,编译执行
小结
该中方法,比 ndk-build 的当时简洁很多,
- 免去了 头文件的编写
- 免去了 Android.mk 文件的编写
- 免去了 单独编译 so 文件的流程
- cpp 引入头文件的写法,比较复杂