新建项目直接选中Native C++即可,本篇文章主要描述如何在现有项目中添加Native方法
添加步骤1.AS中依次点击Preferences->Android SDK -> SDK Tools安装Cmake和NDK,如果安装过程中下载超时,可以关闭代理重试
2.新建声明native方法的类NativeMethod.java。代码如下
public class NativeMethod {
static {
// 这里填入的就是要使用的so库的名字
System.loadLibrary("iBoxChain");
}
// 声明Native方法
public native static String getString();
public native static String getContent();
}
此时,这两个方法是红色的,不能使用状态
3.在src/main目录下建立存放C/C++文件的目录jni
4.新建C++文件NativeMethod.cpp,并添加如下代码
#include
5.在app目录下新建CMakeLists.txt文件,注意这个文件名字不可以修改,添加如下代码
#指定使用cmake的最低版本
cmake_minimum_required(VERSION 3.6)
#指定要生成so库信息,参数分别为:生成的so库名,so库的类别,生成so库的源C++文件
add_library(iBoxChain SHARED src/main/jni/NativeMethod.cpp)
6.右键点击app目录,点击Link C++ Project With Gradle。Build System选择CMake,路径选择第5步中新建的CMakeLists.txt文件,点击确定
此时,我们app目录下的 build.gradle文件里将会多出下列代码
externalNativeBuild {
cmake {
path file('CMakeLists.txt')
}
}
7.回到NativeMethod.java类中,选中标红的getTip(),alter + enter按钮,mac使用option + enter。
将会在iBoxChain.c文件里生成C的方法,这是自动生成的方法。
8.因为我们要使用的是NativeMethod.cpp。所以把生成的方法复制到NativeMethod.cpp中
并删除iBoxChain.c文件。改造NativeMethod.cpp中的方法如下
extern "C"
JNIEXPORT jstring JNICALL
// 方法名与NativeMethod.java文件的全路径相关,定义完成之后,不要修改这两者
Java_com_example_nativetest_NativeMethod_getTip(JNIEnv *env, jclass type) {
return env->NewStringUTF("Hello, I am a new Tip");
}
此时,NativeMethod.java中的方法,就已经和NativeMethod.cpp中的方法建立联系。
按照7中的步骤操作getContent方法,将会自动在NativeMethod.cpp中生成对应的C++方法,补全之后即可使用
9.在代码中调用这两个方法,点击运行即可,运行成功之后,将会在app的build->cmake文件夹下生成对应CPU架构下的so库
常见问题1.什么跟网上一些主流的构建方式不一样?
现在百度上能搜到的教程大多是构建比较简单,使用稍微复杂。但是大多是针对的AS2.2及其以前的版本,在升级到3.0之后,AS使用CMake来构建,因此要通过写构建脚本的形式来进行。而且搭建的过程比较复杂,但是后续使用会比较简单。
2.下载不了NDK是什么原因?
大多时候我们会给Android Studio指定代理以便能翻墙访问到许多开源库。但是Android Stduio官方的某些组件下载时,如果使用代理,AS会失去本地的存储权限,因此即使能访问到这些组件,也下载不下来,关闭代理即可。
3.示例中哪些命名可以自由定制,哪些不可以?
NativeMethod.java和NativeMethod.cpp文件名是可以自由修改的。且两者之间可以不一致
CMakeLists.txt文件名不可以修改,否则无法正常添加选中
System.loadLibrary(“iBoxChain”)和CMakeLists.txt中的iBoxChain为对应关系,前者是使用so库的名字,后者是生成so库的名字。
4.为何不指定生成so库的CPU架构信息
不指定的时候默认多种架构的so库都生成
5.如何把多个cpp文件生成多个so库?
假设此时又有JniTest.cpp,NativeTest.cpp等多个cpp文件。打开CMakeLists.txt文件
add_library (iBoxChain SHARED src/main/jni/NativeMethod.cpp)
add_library (jniTest SHARED src/main/jni/JniTest.cpp)
add_library (NativeTest SHARED src/main/jni/NativeTest.cpp)
这样运行之后,会生成,对应的三个so库,在使用的时候也需要 System.loadLibrary("")逐个添加这些库
6.如何把多个cpp文件生成一个so库?
方法一、假设此时又有JniTest.cpp,NativeTest.cpp等多个cpp文件。打开CMakeLists.txt文件
add_library (iBoxChain SHARED src/main/jni/NativeMethod.cpp src/main/jni/JniTest.cpp)
在后边逐次添加cpp文件的路径,即可把这些文件全部生成到iBoxChain.so中,
但是这样不利于扩展,每次新增一个cpp文件,都要在这里修改
方法二、
file(GLOB SRC_LIST "src/main/jni/*.cpp")
add_library(iBoxChain SHARED ${SRC_LIST})
这中方法可以把指定目录下的所有cpp文件全部添加到iBoxChain.so中,缺点是不够灵活,
有些需要生成到其他so库必须要额外建立文件夹保存