NDK
NDK 全称是 Native Development Kit,是一组可以在 Android 应用中编写实现 C/C++ 的工具,可以在项目用自己写源代码构建,也可以利用现有的预构建库。
用途
- 从设备获取更好的性能以用于计算密集型应用,例如游戏或物理模拟
- 重复使用自己或其他开发者的 C/C++ 库,便利于跨平台。
- NDK 集成了譬如 OpenSL、Vulkan 等 API 规范的特定实现,以实现在 java 层无法做到的功能如提升音频性能等
- 增加反编译难度
C&C++ - 写给Android应用开发者的C语言快速入门指北
NDK开发入门终极教程
1 准备工作
1.1 下载 NDK
当前 NDK 稳定版已经 发布到 r15c
。附上各个平台的下载地址:
- android-ndk-r15c-windows-x86
- android-ndk-r15c-windows-x86_64
- android-ndk-r15c-darwin-x86_64
- android-ndk-r15c-linux-x86_64
1.2 添加NDK依赖
解压下载好的文件在本地,在 AndroidStudio 工程配置(注意不是 AndroidStudio 工具配置)中指定 NDK 路径。
选中项目,F4弹出
Project Structure
,在SDK Location
中找到 ndk 项,选择本地ndk路径。或在
local.properties
中指定NDK路径1
2nkd.dir=ndk本地路径
sdk.dir=sdk本地路径
1.3 添加cmake支持
在 AndroidStudio 工具配置中,选择 Android SDK -> SDK Tools 中,勾选CMake并安装。
2 新建支持NDk工程
现在的AndroidStduio
更支持一种极简方式集成NDK
开发支持,即在下图中勾选include C++ support
。然后选择C++
标准。如C++ 11
。建选默认的ToolChain Default
。
之后正常 run 即可将 C 语言部分生成出 so 文件并打包到 apk 文件中。
3 给工程添加NDK支持
上述方式适合在新的工程中添加 NDK 支持。如何要在现有的项目中添加 NDK 支持,现提供 cmake
和 ndk-build
两种方式。
由于在同一个工程中,同时支持 cmake
和 ndk-build
两种方式编译 so 文件,因此将 C 源码单独放在 cpp-src
目录。且将 cmake
、ndk-build
区分不同的module
进行编译。
3.1 cmake
这是目前最受欢迎的集成方式,AndroidStduio 在创建新工程时默认使用该方式添加 NDK 支持。但在现有的工程中添加 NDK支持,需要手动配置。
创建 cmake module 添加个三个文件。
CMakeLists.txt
cmake编译配置文件
1 | cmake_minimum_required(VERSION 3.4.1) |
AndroidManifest.xml
每个module必须的配置文件,指定packageName。
1 |
|
build.gradle
每个module必须的配置文件,用于构建项目。
1 | apply plugin: 'com.android.library' |
关于 CMake 编译参数的设置,更多内容请阅读官方资料。
眼尖的小伙伴已经发现两处配置了 externalNativeBuild
。其中第二处的externalNativeBuild
配置是生成Gradle Task
可以不运行工程,直接在 ndk-cmake -> Tasks -> other 找到编译 so 文件有关的四个任务。
双击 exeternalNativeBuildDebug
执行任务,根据路径即可找到生成的so文件。
3.2 ndk-build
这是最传统的 ndk 编译方式。在配置得当的情况下,可以在不打开 AndroidStudio 情况下完成so文件的编译和输出。
创建 ndk-build module ,添加4个文件。
1 | # 讲真,这个参数我看不懂。从 官方demo 抄来的。用于指定源文件的时候使用 |
关于 Android.mk 编译参数的设置,更多内容请阅读官方资料
1 | # 指定编译的的so版本 |
关于 Application.mk 编译参数的设置,更多内容请阅读官方资料
AndroidManifext.xml
1 |
|
build.gradle
1 | apply plugin: 'com.android.library' |
上面的externalNativeBuild
作用同 CMake
方式的一样,用于编译生成 so 文件。 但是 ndk-build 还支持使用命令ndk-build
编译 so 文件。 需要将 NDK 路径添加至环境变量。
需要在jni
目录下执行该命令:
最后生成的so文件路径如图;
4 实践
4.1 生成头文件
在主 module 中的 MainActivity中添加 native 方法 。使用 javah 编译出头文件。 使用 -d
参数指定头文件的输出目录。
1 | public class MainActivity extends Activity { |
在 app/src/main/java
目录下执行命令 javah
1 | javah -d ../../../../cpp-src/ com.flueky.demo.MainActivity |
4.2 编写 C 源码
在hello-jni.c
文件引用生成的头文件,并编写测试代码。
1 |
|
4.3 运行截图
页面截图:
日志截图:
5 源码获取
工程源码已开放在GitHub,下载地址。可以直接编写 C 源码并进行调试和生成 so 文件。