我使用的是android studio 2.3.3版本,搭建ndk开发环境比较简单,打开File----Settings----Appearance&Behavior----System Settings----Android SDK,选择SDK Tools,将CMake,LLDB,NDK 前的复选框勾上,点击Apply,而后就是等待ndk下载完成。html
安装成功后,右键项目----open module setting,Android NDK location会自动赋值java
建立ndk项目和普通android项目有一点区别,须要把Include C++ support前面的复选框勾上,而后直接下一步。但在最后一步,有一个c++下拉框选项,能够根据你的实际状况适当修改,C++ Standard :点击下拉框,能够选择标准 C++,或者选择默认 CMake 设置的 Toolchain Default 选项。Exceptions Support :若是你想使用有关 C++ 异常处理的支持,就勾选它。勾选以后,Android Studio 会在 module 层的 build.gradle 文件中的 cppFlags 中添加 -fexcetions 标志。Runtime Type Information Support :若是你想支持 RTTI,那么就勾选它。勾选以后,Android Studio 会在 module 层的 build.gradle 文件中的 cppFlags 中添加 -frtti 标志。android
项目建立好后,app下多了一个cpp目录,该目录用于存放c程序的源码,头文件,预编译项目等,android studio 会默认帮咱们建立一个native-lib.cpp文件,该文件已有一个测试方法,结构图以下:c++
经过上图看到,在External Build Files 下面多了一个CMakeLists.txt文件,该文件用于c程序须要生成so文件的配置文件。编程
cmake_minimum_required(VERSION 3.4.1):这是版本信息,咱们不用管它app
add_library():这个命令是,经过add.library()定义多个库,CMake会去自动构建他们,一个*.cpp文件对应一个add_library命令.
ide
add_library( # Sets the name of the library.生成so文件的名字,建议和cpp文件同名 native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). 须要生成so文件的cpp文件名称 src/main/cpp/native-lib.cpp )
find_library():定位 NDK library 的位置,并将其位置存储在一个变量之中。在构建脚本的其余地方使用这个变量,来代指 NDK library。下面的示例代码将 Android-specific log support library 的位置存储到变量 log-lib 中测试
find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log )
如今咱们来看native-lib.cpp文件,这是as帮咱们自动生成好的,返回是一个Hello from C++的字符串。gradle
#include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_serialport_com_ndkjnidemo_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); }
JNIEXPORT jstring JNICALL 这里的jstring表明返回值, 参数JNIEnv* env,表明指针,jobject 表明调用这个方法的对像(普通方法是jobject,静态方法是jclass)后面的参数和java类中定义的本地方法对数相对应,方法命名规则:Java_包名_调用jni方法的类名_方法名,android studio 帮咱们
生成的程序,activity包名是serialport.com.ndkjnidemo,类名是MainActivity,方法名是stringFromJNI,因此native-lib.cpp方法名称为:Java_serialport_com_ndkjnidemo_MainActivity_stringFromJNI,其中返回值类型和java数据类型对应以下
若是咱们须要写多个jni方法,*.cpp格式以下:ui
//方法一 extern "C" JNIEXPORT jstring JNICALL Java_serialport_com_ndkjnidemo_MainActivity_test1( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } //方法二 extern "C"//若是不写extern "C" java是没法调用到这里定义的方法 JNIEXPORT jstring JNICALL Java_serialport_com_ndkjnidemo_MainActivity_test2( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); }
最后咱们来看自动生成的MainActivity,在onCreate中调用stringFromJNI,而后给文本组件赋值,软件运行参见图一
package serialport.com.ndkjnidemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
static {
//native-lib值来自,CMakeLists.txt文件中,add_library命令的第一个参数 System.loadLibrary("native-lib"); }
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
public native String stringFromJNI();
}
代码都是android studio自动自成的,因此此处不上传代码,demo运行结果:
参考文章: