NDK学习系列--第二篇
简介
本篇将介绍android ndk项目的结构。新建后的ndk项目如下图所示:
1、cpp目录详解
首先可以看到main包下面多了cpp目录,里面包括CMakeLists.txt文件,CMakeLists.txt是CMake的构建脚本,作用相当于Android项目的gradle配置。代码如下:
# 设置Cmake最小版本
cmake_minimum_required(VERSION 3.4.1)
# 编译library
add_library(# 设置library名称
native-test1
# 设置library模式
# SHARED模式会编译so文件,STATIC模式不会编译
SHARED
# 设置原生代码路径
native-test.cpp )
add_library(# Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# 设置原生代码路径
native-lib.cpp )
# 用来定位的library
find_library(# 设置library名称
log-lib
# 将library路径存储为一个变量,可以在其他地方用这个变量引用NDK库
# 在这里设置变量名称
log )
target_link_libraries(# 关联的library
native-test1
native-lib
# 关联native-lib和log-lib
${log-lib} )
可以看到我这里有两个add_library,我是分开来写的也可以通过aux_source_directory来指定一个目录。批量设置cpp文件, 使得可以查找目录下的所有源文件,并将名称保存到 DIR_SRCS 变量。代码示例如下:
aux_source_directory(src/main/cpp DIR_SRCS)
add_library(# Sets the name of the library.
ffmpeg
SHARED
${DIR_SRCS})
也可以只用一个add_library,设置的路径之间用空格分开。
add_library(# Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# 设置原生代码路径
native-lib.cpp md5.cpp)
cpp目录下面其他的文件则是c++的源码文件了,我们可以在里面用c++来实现功能,提供接口给Java调用。
2、gradle与普通项目的区别
可以看到多了externalNativeBuild这个配置,defaultConfig里面的的externalNativeBuild主要是用于配置Cmake的命令参数,比如可以通过abifilter "armeabi"配置只生成armeabi的so库。而外部的 externalNativeBuild的主要是定义了CMake的构建脚本CMakeLists.txt的路径。
3、代码示例
native-lib.cpp的代码:
#include
#include
extern "C" JNIEXPORT jstring JNICALL
Java_com_yao_ndkdemo_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello ="Hello from C++";
return env->NewStringUTF(hello.c_str());
}
MainActivity 的代码:
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-test1");
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI1());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native StringstringFromJNI();
public native StringstringFromJNI1();
}
Java调用c++的接口,需要注意c++的方法名是Java_com_yao_ndkdemo_MainActivity_stringFromJNI对应Java的public native String stringFromJNI()方法。com_yao_ndkdemo是包名。