简介
Nativie Develop Kit 原生开发套件
NDK 是一套工具,使您能够在 Android 应用中使用 C 和 C++ 代码,并提供众多平台库,您可使用这些平台库管理原生 Activity 和访问实体设备组件,例如传感器和触摸输入。
使用场景及基础概念
使用场景
- 进一步提升设备性能,以降低延迟或运行游戏或物理模拟等计算密集型应用
- 重复使用您自己或其他开发者的 C 或 C++ 库
基础概念
JNI
- Java Native Interface
指 Java 原生接口。它定义了 Android 从受管理代码(使用 Java 或 Kotlin 编程语言编写)编译的字节码与原生代码(使用 C/C++ 编写)互动的方式。JNI 不依赖于供应商,支持从动态共享库加载代码,虽然有时较为繁琐,但效率尚可。
ndk-build
- ndk-build + Android.mk + Application.mk
NDK 工具包中提供了完整的一套将 c/c++ 代码编译成静态/动态库的工具,而 Android.mk 和 Application.mk 你可以认为是描述编译参数和一些配置的文件。比如指定使用c++11还是c++14编译,会引用哪些共享库,并描述关系等,还会指定编译的 abi。只有有了这些 NDK 中的编译工具才能准确的编译 c/c++ 代码。
ndk-build文件 是 Android NDK r4 中引入的一个 shell 脚本。为了调用正确的 NDK 构建脚本。其实最终还是会去调用 NDK 自己的编译工具。
Android.mk 文件位于项目 jni/ 目录的子目录中,用于向构建系统描述源文件和共享库。 它实际上是构建系统解析一次或多次的微小 GNU makefile 片段。 Android.mk 文件用于定义 Application.mk、构建系统和环境变量所未定义的项目范围设置。 它还可替换特定模块的项目范围设置。
Application.mk:它是一个构建文件,此文件用于描述应用需要的原生模块。 模块可以是静态库、共享库或可执行文件。实际上是定义要编译的多个变量的微小 GNU Makefile 片段。
CMake
- CMake + CMakeLists.txt
CMake是个一个开源的跨平台自动化建构系统,用来管理软件建置的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个库。 它用配置文件控制建构过程(build process)的方式和Unix的make相似,只是CMake的配置文件取名为CMakeLists.txt。CMake并不直接建构出最终的软件,而是产生标准的建构档(如GNU的Makefile或Windows Visual C++的projects/workspaces),然后再依一般的建构方式使用。
ABI
不同的 Android 设备使用不同的 CPU,而不同的 CPU 支持不同的指令集。CPU 与指令集的每种组合都有专属的应用二进制接口 Application Binary Interface (ABI)。ABI 包含以下信息:
- 可使用的 CPU 指令集(和扩展指令集)。
- 运行时内存存储和加载的字节顺序。Android 始终是 little-endian。
- 在应用和系统之间传递数据的规范(包括对齐限制),以及系统调用函数时如何使用堆栈和寄存器。
- 可执行二进制文件(例如程序和共享库)的格式,以及它们支持的内容类型。Android 始终使用 ELF。
- 如何重整 C++ 名称。(Name Mangling 二进制模块兼容性不好)
LLDB
LLDB是Low Lever Debugger的简称,翻译成中文应该叫做底层调试器,它是LLVM项目的调试器组件。LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。
使用方式
开发环境
主要组件
- 原生共享库:NDK 从 C/C++ 源代码构建这些库或 .so 文件。
- 原生静态库:NDK 也可构建静态库或 .a 文件,而您可将静态库关联到其他库。
- Java 原生接口 (JNI)
- 应用二进制接口 (ABI)
- 清单(AndroidManifest.xml):如果您编写的应用不包含 Java 组件,必须在清单中声明 NativeActivity 类。
执行流程
- 设计应用,确定要使用 Java 实现的部分,以及要以原生代码形式实现的部分。
- 注意:虽然可以完全避免使用 Java,但您可能会发现 Android Java 框架对于控制显示和界面等任务很有用。
- 像创建任何其他 Android 项目一样创建一个 Android 应用项目。
- 如果要编写纯原生应用,请在 AndroidManifest.xml 中声明 NativeActivity 类。
- 在“JNI”目录中创建一个描述原生库(包括名称、标记、关联库和要编译的源文件)的 Android.mk 文件。
- 或者,您也可以创建一个配置目标 ABI、工具链、发布/调试模式和 STL 的 Application.mk 文件。对于其中任何您未指明的项,将分别使用以下默认值:
- ABI:所有非弃用的 ABI
- 模式:发布
- STL:系统
- 将原生源代码放在项目的 jni 目录下。
- 使用 ndk-build 编译原生(.so、.a)库。
- 构建 Java 组件,生成可执行 .dex 文件。
- 将所有内容封装到一个 APK 文件中,包括 .so、.dex 以及应用运行所需的其他文件
延伸
高性能音频
- 音频延迟
- 音频采样
- AAudio
- OpenSL ES
- 原生 MIDI API
- Oboe
Vulkan API
- 图形处理API
- 简单点说就是GPU API
- 再简单点甩翻OpenGL/OpenGL SE
- 不过开发代码全靠自己 没有OpenGL好调用
Neural Networks API
Android Neural Networks API (NNAPI) 是一个 Android C API,专为在 Android 设备上运行计算密集型运算从而实现机器学习而设计。NNAPI 旨在为更高层级的机器学习框架(如 TensorFlow Lite 和 Caffe2)提供一个基本功能层,用来建立和训练神经网络。搭载 Android 8.1(API 级别 27)或更高版本的所有 Android 设备上都提供该 API。
图像解码器
NDK ImageDecoder API 提供了一种标准 API,供 Android C/C++ 应用直接解码图像。应用开发者不再需要使用 Java API(通过 JNI)或第三方图像解码库。此 API 与 Bitmap 模块中的编码函数结合使用,可实现以下功能:
- 缩小原生应用和库的大小,因为它们不再需要链接自己的解码库。
- 应用和库可自动从解码库的平台安全更新中受益。
- 应用可以直接将图像解码到其提供的内存中。然后,应用可以对图像数据进行后处理(如果需要),并将其传递给 OpenGL 或其绘制代码。