Android 在现有项目中使用NDK开发

Hayley ·
更新时间:2024-11-13
· 713 次阅读

新建项目直接选中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库必须要额外建立文件夹保存


作者:YX_BB



ndk Android

需要 登录 后方可回复, 如果你还没有账号请 注册新账号