Android NDK 原生 API

Android NDK 提供一组随新的 Android API 级别后续发布而逐渐增加的原生标头和共享库文件。本页介绍这些标头和文件,并将其与特定的 Android API 级别进行对应。

使用原生 API

请遵循以下两个基本步骤,以便您的应用使用 NDK 提供的库:

  1. 在您的代码中添加与您想使用的库关联的标头。
  2. 通知构建系统您的原生模块需要在加载时链接库。
    • 如果您使用 ndk-build:添加原生库到您 Android.mk 文件的 LOCAL_LDLIBS 变量。例如,要链接 /system/lib/libfoo.so,请添加以下行:
    • LOCAL_LDLIBS := -lfoo
      

      若要列出多个库,请使用空格作为分隔符。如需了解有关使用 LOCAL_LDLIBS 变量的详细信息,请参阅 Android.mk

    • 如果您使用 CMake:遵循向您的项目添加 C 和 C++ 代码中的说明。
对于所有 API 级别,构建系统将自动链接标准 C 和 C++ 库。无需在设置 LOCAL_LDLIBS 时明确添加这些库。

NDK 通常为新的 Android 版本提供新的标头和库。如需获取 Android 发行版引入的原生 API 列表,请查看下方的表 1。这些文件位于 NDK 安装根目录下的 sysroot/usr/include 中。

下表显示支持 NDK 的 API 级别和 Android 平台版本之间的对应关系。如需了解有关 Android API 级别的详细信息,请参阅什么是 API 级别?

表 1. Android 版本引入的关键原生 API 支持摘要。

支持 NDK 的 API 级别 Android 平台版本 关键原生 API 添加
3 1.5 C 标准库 (libc/libm) #include ...
C++ #include ...
Java 原生接口 #include <jni.h>
Android 日志记录 API #include <android/log.h>
Zlib #include <zlib.h>
动态链接器 #include <dlfcn.h>
4 1.6 OpenGL ES1.x #include <GLES/gl.h>
#include <GLES/glext.h>
5 2.0 - 2.1.x OpenGL ES 2.0 #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
8 2.2 Android 位图 API #include <android/bitmap.h>
9 2.3 - 3.0.x EGL #include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
OpenSL ES #include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Platform.h>
#include <SLES/OpenSLES_Android.h>
#include <SLES/OpenSLES_AndroidConfiguration.h>
原生应用 API 事件循环:
#include <android/looper.h>

输入事件:
#include <android/input.h>
#include <android/keycodes.h>

传感器事件:
#include <android/sensor.h>

窗口/界面管理:
#include <android/rect.h>
#include <android/window.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>

资产:
#include <android/asset_manager.h>

配置:
#include <android/configuration.h>

OBB 文件:
#include <android/storage_manager.h>

#include <android/obb.h>

原生 Activity:
#include <android/native_activity.h>
12 3.1.x
13 3.2
14 4.0 - 4.0.2 OpenMAX AL #include <OMXAL/OpenMAXAL.h>
#include <OMXAL/OpenMAXAL_Platform.h>
#include <OMXAL/OpenMAXAL_Android.h>
15 4.0.3、4.0.4
16 4.1、4.1.1
17 4.2、4.2.2
18 4.3 OpenGL ES 3.0 #include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
19 4.4、4.4w
21 5.0、5.1 OpenGL ES 3.1 #include <GLES3/gl31.h>
#include <GLES3/gl3ext.h>
原生媒体 API #include <media/NdkMediaCodec.h>
#include <media/NdkMediaCrypto.h>
#include <media/NdkMediaDrm.h>
#include <media/NdkMediaError.h>
#include <media/NdkMediaExtractor.h>
#include <media/NdkMediaFormat.h>
#include <media/NdkMediaMuxer.h>
23 6.0 原生跟踪 API #include <android/trace.h>
24 7.0 - 7.1.1 Vulkan #include <vulkan/vulkan.h>
原生相机 API #include <camera/NdkCameraCaptureSession.h>
#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraError.h>
#include <camera/NdkCameraManager.h>
#include <camera/NdkCameraMetadata.h>
#include <camera/NdkCameraMetadataTags.h>
#include <camera/NdkCaptureRequest.h>
原生 choreographer API #include <android/choreographer.h>
原生多网络 API #include <android/multinetwork.h>
OpenGL ES 3.2 #include <GLES3/gl32.h>
#include <GLES3/gl3ext.h>
原生媒体 API #include <media/NdkImage.h>
#include <media/NdkImageReader.h>
26 8.0 AAudio API #include <aaudio/AAudio.h>
硬件缓冲区 API #include <android/hardware_buffer.h>
#include <android/hardware_buffer_jni.h>>
共享内存 API #include <android/sharedmem.h>
27 8.1 神经网络 API #include <android/NeuralNetworks.h>
共享内存 JNI API #include <android/hardware_buffer.h>>

原生 API 重要内容

Android API 级别 3

C 库

标准 C 库标头可根据其常用名称获得,例如:<stdlib.h><stdio.h>。请注意,与 Linux 不同,在 Android 上不存在单独的 pthread 库和 rt 库。该功能包含在 libc 中。数学库在 libm 中保持独立,但由编译器自动添加。

动态链接器库

您可使用 Android 动态链接器的 dlopen(3) 和 dlsym(3) 功能。此外,您还必须链接 libdl。例如:
LOCAL_LDLIBS := -ldl

C++ 库

提供 C++17 支持。如需了解有关 C++ 库支持的详细信息,请参阅 C++ 库支持

Android 特定的日志支持

<android/log.h> 包含各种不同的函数,应用可使用这些函数从原生代码向 logcat 发送日志消息。如需了解有关这些定义的详细信息,请参阅日志记录文档。一般而言,您应自行编写包装器宏以使用此功能。如果您想要记录日志,请链接到 liblog。例如:
LOCAL_LDLIBS := -llog

ZLib 压缩库

通过添加 zlib.hzconf.h,您可以使用 Zlib 压缩库。您还必须通过在 Android.mk 文件中添加以下行,将您的原生模块链接到 /system/lib/libz.so

LOCAL_LDLIBS := -lz

Android API 级别 4

NDK 为开发在 Android 1.6 系统映像及更高版本上运行的原生代码提供下列 API。

OpenGL ES 1.x 库

标准 OpenGL ES 标头 <GLES/gl.h><GLES/glext.h> 包含从原生代码执行 OpenGL ES 1.x 渲染调用所需的声明。

如需使用这些标头,通过在 Android.mk 文件中添加以下行,将您的原生模块链接到 /system/lib/libGLESv1_CM.so

LOCAL_LDLIBS := -lGLESv1_CM

所有基于 Android 的设备均支持 OpenGL ES 1.0,因为 Android 提供一个启用 Open GL 1.0 的软件渲染器,可在没有 GPU 的设备上使用。

仅具有所需 GPU 的 Android 设备才完全支持 OpenGL ES 1.1。应用可以查询 OpenGL ES 版本字符串和扩展字符串,以确定当前设备是否支持其需要的功能。如需了解有关如何执行此查询的信息,请参阅 OpenGL 规范中的 glGetString() 说明。

此外,您必须在您的清单文件中放置一个 <uses-feature> 标签,以指明您的应用所需的 OpenGL ES 版本。

从 API 级别 9 才开始提供 EGL API。不过,您可以使用 VM 执行您从这些 API 获取的部分操作。这些操作包括表面创建和翻页。有关如何使用 GLSurfaceView 的示例,请参阅 GLSurfaceView 简介

san-angeles 示例应用提供一个示例,展示如何执行这些操作,从而在原生代码中渲染每个帧。此示例是出色的 San Angeles Observation 演示程序的小型 Android 端口。

Android API 级别 5

NDK 为开发在 Android 2.0 系统映像及更高版本上运行的原生代码提供下列 API。

OpenGL ES 2.0 库:

标准 OpenGL ES 2.0 标头 <GLES2/gl2.h><GLES2/gl2ext.h> 包含从原生代码执行 OpenGL ES 2.0 渲染调用所需的声明。这些渲染调用提供利用 GLSL 语言定义并使用顶点和片段着色器的功能。

如需使用 OpenGL ES 2.0,通过在 Android.mk 文件中添加以下行,将您的原生模块链接到 /system/lib/libGLESv2.so

LOCAL_LDLIBS := -lGLESv2

并非所有设备均支持 OpenGL ES 2.0。应用可以查询 OpenGL ES 版本字符串和扩展字符串,以确定当前设备是否支持其需要的功能。如需了解有关如何执行此查询的信息,请参阅 OpenGL 规范中的 glGetString() 说明。

此外,您必须在您的清单文件中放置一个 <uses-feature> 标签,以指明您的应用所需的 OpenGL ES 版本。如需了解有关针对 <uses-feature> 的 OpenGL ES 设置的详细信息,请参阅 OpenGL ES

hello-gl2 示例应用提供一个基本示例,展示如何将 OpenGL ES 2.0 与 NDK 结合使用。

从 API 级别 9 才开始提供 EGL API。不过,您可以使用 VM 执行您从这些 API 获取的部分操作。这些操作包括表面创建和翻页。有关如何使用 GLSurfaceView 的示例,请参阅 GLSurfaceView 简介

Android API 级别 8

NDK 为开发在 Android 2.2 系统映像及更高版本上运行的原生代码提供下列 API。

jnigraphics

jnigraphics 库显示一个基于 C 的接口,其允许原生代码以可靠方式访问 Java 位图对象的像素缓冲区。使用 jnigraphics 的工作流程如下:

  1. 使用 AndroidBitmap_getInfo() 从 JNI 检索信息,如既定位图句柄的宽度和高度。
  2. 使用 AndroidBitmap_lockPixels() 锁定像素缓冲区并检索指向它的指针。执行此操作可确保像素在应用调用 AndroidBitmap_unlockPixels() 之前不会移动。
  3. 在原生代码中,修改像素缓冲区使其符合相应像素格式、宽度和其他特性。
  4. 调用 AndroidBitmap_unlockPixels() 以解锁缓冲区。

如需使用 jnigraphics,在您的源代码中添加 <bitmap.h> 标头,并通过在您的 Android.mk 文件中添加以下行链接 jnigraphics

LOCAL_LDLIBS += -ljnigraphics

有关此功能的其他详细信息,请参阅 <android/bitmap.h> 文件的注释。

Android API 级别 9

NDK 为开发在 Android 2.3 系统映像及更高版本上运行的原生代码提供下列 API。

EGL

EGL 为分配和管理 OpenGLES 表面提供原生平台接口。如需了解有关其功能的详细信息,请参阅 EGL 原生平台接口

EGL 允许您从原生代码执行以下操作:

  • 列出支持的 EGL 配置。
  • 分配和释放 OpenGLES 表面。
  • 切换或翻转表面。

以下标头提供 EGL 功能:

  • <EGL/egl.h>:主要的 EGL API 定义。
  • <EGL/eglext.h>:EGL 扩展相关的定义。

若要链接系统的 EGL 库,将以下行添加到您的 Android.mk 文件:

LOCAL_LDLIBS += -lEGL

OpenSL ES

Android 原生音频处理基于 Khronos Group OpenSL ES 1.0.1 API。

标准 OpenSL ES 标头 <SLES/OpenSLES.h><SLES/OpenSLES_Platform.h> 包含从 Android 原生端执行音频输入和输出所需的声明。OpenSL ES 的 NDK 分发还提供 Android 特定的扩展。如需了解有关这些扩展的信息,请参阅 <SLES/OpenSLES_Android.h><SLES/OpenSLES_AndroidConfiguration.h> 中的注释。

系统库 libOpenSLES.so 实现公共原生音频功能。通过向 Android.mk 文件添加以下行来进行链接:

LOCAL_LDLIBS += -lOpenSLES

如需了解有关 OpenSL ES API 的详细信息,请参阅面向 Android 的 OpenSL ES

Android 原生应用 API

从 API 级别 9 开始,您可以使用原生代码编写整个 Android 应用,无需使用任何 Java。

注:在原生代码中编写您的应用本身并不能让您的应用在 VM 中运行。此外,您的应用仍必须通过 JNI 访问 Android 平台的大部分功能。

此版本提供下列原生标头:

如需了解有关这些标头的详细信息,请参阅 NDK API 参考文档,以及标头本身的注释。另外,如需了解有关编写原生应用这一较大主题的详细信息,请参阅原生 Activity 和应用

当您添加其中一个或多个标头时,您也必须要链接 libandroid.so 库。若要链接 libandroid.so,请在您的 Android.mk 文件中添加以下行:

LOCAL_LDLIBS += -landroid

Android API 级别 14

NDK 为开发在 Android 4.0 系统映像及更高版本上运行的原生代码提供下列 API。

OpenMAX AL

Android 原生多媒体处理基于 Khronos Group OpenMAX AL 1.0.1 API。

标准 OpenMAX AL 标头 <OMXAL/OpenMAXAL.h><OMXAL/OpenMAXAL_Platform.h> 包含从 Android 原生端执行多媒体输出所需的声明。

OpenMAX AL 的 NDK 分发还提供 Android 特定的扩展。如需有关这些扩展的信息,请参阅 <OMXAL/OpenMAXAL_Android.h> 中的注释。

系统库 libOpenMAXAL.so 实现公共原生多媒体功能。若要链接此库,在您的 Android.mk 文件中添加以下行:

    LOCAL_LDLIBS += -lOpenMAXAL

如需了解有关此主题的详细信息,请参阅 $NDK/docs/openmaxal/index.html,其中 $NDK 是您安装 NDK 的根目录。

OpenSL ES

针对此 Android API 级别的 OpenSL ES 支持增加了 PCM 支持。如需了解有关 NDK 中 OpenSL ES 支持的详细信息,请参阅 OpenSL ES

Android API 级别 18

NDK 为开发在 Android 4.3 系统映像及更高版本上运行的原生代码提供下列 API。

OpenGL ES 3.0

标准 OpenGL ES 3.0 标头 <GLES3/gl3.h><GLES3/gl3ext.h> 包含从原生代码执行 OpenGL ES 3.0 渲染调用所需的声明。这些渲染调用提供利用 GLSL 语言定义并使用顶点和片段着色器的功能。

若要使用 OpenGL ES 3.0,通过在您的 Android.mk 文件中添加以下行,将您的原生模块链接到 /system/lib/libGLESv3.so

LOCAL_LDLIBS := -lGLESv3

并非所有设备均支持 OpenGL ES 3.0。应用可以查询 OpenGL ES 版本字符串和扩展字符串,以确定当前设备是否支持其需要的功能。如需了解有关如何执行此查询的信息,请参阅 OpenGL 规范中的 glGetString() 说明。

此外,您必须在您的清单文件中放置一个 <uses-feature> 标签,以指明您的应用所需的 OpenGL ES 版本。如需了解有关针对 <uses-feature> 的 OpenGL ES 设置的详细信息,请参阅 OpenGL ES

gles3jni 示例应用提供一个基本示例,展示如何将 OpenGL ES 3.0 与 NDK 结合使用。

Android API 级别 21

NDK 为开发在 Android 4.3 系统映像及更高版本上运行的原生代码提供下列 API。

OpenGL ES 3.1

标准 OpenGL ES 3.1 标头 <GLES3/gl31.h><GLES3/gl3ext.h> 包含从原生代码执行 OpenGL ES 3.1 渲染调用所需的声明。这些渲染调用提供利用 GLSL 语言定义并使用顶点和片段着色器的功能。

如需使用 OpenGL ES 3.1,通过在您的 Android.mk 文件中添加以下行,将您的原生模块链接到 /system/lib/libGLESv3.so

LOCAL_LDLIBS := -lGLESv3

并非所有设备均支持 OpenGL ES 3.1。应用可以查询 OpenGL ES 版本字符串和扩展字符串,以确定当前设备是否支持其需要的功能。如需了解有关如何执行此查询的信息,请参阅 OpenGL 规范中的 glGetString() 说明。

此外,您必须在您的清单文件中放置一个 <uses-feature> 标签,以指明您的应用所需的 OpenGL ES 版本。如需了解有关针对 <uses-feature> 的 OpenGL ES 设置的详细信息,请参阅 OpenGL ES

gles3jni 示例应用提供一个基本示例,展示如何将 OpenGL ES 3.1 与 NDK 结合使用。

:Android 模拟器不支持 OpenGL ES 3.1 硬件模拟。运行和测试使用此 API 的代码需要一个其硬件可支持 OpenGL ES 3.1 的真实设备。

Android API 级别 23

NDK 为开发在 Android 6.0 及更高版本系统映像上运行的原生代码引入下列 API。

跟踪

原生跟踪 API (<android/trace.h>) 采用 Java 编程语言,提供效果等同 android.os.trace 方法的原生 API。此 API 通过将跟踪记录事件写入系统跟踪缓冲区,让您能够跟踪原生代码中的指定工作单元。然后,您可通过使用 Systrace 工具来收集和分析跟踪事件。如需了解有关使用此 API 的详细信息,请参阅原生跟踪

Android API 级别 24

NDK 为开发在 Android 7.0 及更高版本系统映像上运行的原生代码引入下列 API。

Vulkan

Vulkan 是一种低消耗的跨平台 API,适用于高性能 3D 图形渲染。Vulkan 是由 Khronos Group 维护的一种开放标准。标准 <vulkan/vulkan.h> 标头文件包含从原生代码执行 Vulkan 渲染调用所需的声明。

如需了解有关在您 Android 应用中使用 Vulkan 的详细信息,请参阅 API 文档。对于代码示例,请参阅 GitHub 上的 vulkan-basic-samplesandroid-vulkan-tutorials 项目。

相机

原生相机 API 采用 Java 编程语言,提供效果等同 android.hardware.camera2 类的原生 API。您可利用原生相机 API,在原生代码中执行细粒照片捕获及处理。与 Java camera2 API 不同,原生相机 API 不支持已弃用的相机 HAL 1.0 实现(即,原生相机 API 中的可用相机列表不会列出达到 LEGACY 硬件级别的相机设备)。

Choreographer

原生 choreographer API (<android/choreographer.h>) 采用 Java 语言,提供效果等同 android.view.Choreographer 类的原生 API。您可利用原生 choreographer API,在原生代码中协调动画、输入和绘图的时间。此 API 有助于与 vsync 实现同步,对帧同步非常有用。有关如何使用 choreographer API 的示例,请参阅 GitHub 上 Teapots 示例项目中的 choreographer-30fps 目录。

多网络

原生多网络 API (<android/multinetwork.h>) 提供与 Android 5.0 中添加的 Java 多网络 API 相同功能的原生代码访问权限。

EGL

适用于 Android API 级别 24 的 EGL 支持增加了对以下扩展的支持:

如需了解有关 NDK 中 EGL 支持的详细信息,请参阅 EGL

OpenGL ES 3.2

标准 OpenGL ES 3.2 标头 <GLES3/gl32.h><GLES3/gl3ext.h> 包含从原生代码执行 OpenGL ES 3.2 渲染调用所需的声明。

若要使用 OpenGL ES 3.2,通过在您的 Android.mk 文件中添加以下行,将您的原生模块链接到 /system/lib/libGLESv3.so

LOCAL_LDLIBS := -lGLESv3

并非所有设备均支持 OpenGL ES 3.2。应用可以查询 OpenGL ES 版本字符串和扩展字符串,以确定当前设备是否支持其需要的功能。如需了解有关如何执行此查询的信息,请参阅 OpenGL 规范中的 glGetString() 说明。

此外,您必须在您的清单文件中放置一个 <uses-feature> 标签,以指明您的应用所需的 OpenGL ES 版本。如需了解有关针对 <uses-feature> 的 OpenGL ES 设置的详细信息,请参阅 OpenGL ES

Android API 级别 26

NDK 为开发在 Android 8.0 及更高版本系统映像上运行的原生代码引入下列 API。

AAudio

NDK 为需要低延迟时间的高性能音频应用引入 AAudio API (<aaudio/AAudio.h>)。使用 AAudio 的应用在音频流中读取和写入数据。AAudio 旨在提供比使用 OpenSL ES 更便捷的方式。如需有关使用此 API 的详细信息,请参阅 AAudio 开发者指南

硬件缓冲区

NDK 引入两个原生 API,助您针对跨进程缓冲区管理创建自己的管道。

您可利用原生硬件缓冲区 API (<android/hardware_buffer.h>),直接分配缓冲区,以针对跨进程缓冲区管理创建自己的管道。您可分配 AHardwareBuffer 结构,并通过 eglGetNativeClientBufferANDROID 扩展将其用于获取 EGLClientBuffer 资源类型。您可将此缓冲区传递到 eglCreateImageKHR,以创建 EGLImage 资源类型,随后此资源类型可能会在支持的设备上通过 glEGLImageTargetTexture2DOES 与纹理绑定。此方法可用于创建可跨进程共享的纹理。

您可利用原生硬件缓冲区 JNI API (<android/hardware_buffer_jni.h>),获取一个 HardwareBuffer 对象,即 Parcelable,以便在两个不同进程之间传输。如此,您的应用可获得与 SurfaceFlinger 相似的功能(例如,在不同进程之间创建自己的缓冲区队列),而无需访问内部 Android API。

共享内存

共享内存 API (<android/sharedmem.h>) 是 Android 原生共享内存的包装器,可用于进程间通信。创建共享内存后,系统将返回文件描述符作为句柄。通过使用 mmap() 完成文件描述符与进程内存空间的映射后,您可访问共享内存中的内容。若要移除映射,请调用 munmap()。文件描述符可通过 UNIX 网域套接字与其他进程进行交换。关闭相关文件描述符并移除所有进程中的所有内存映射后,系统会释放已分配的共享内存。

Android API 级别 27

NDK 为开发在 Android 8.1 及更高版本系统映像上运行的原生代码引入下列 API。

神经网络 API

神经网络 API (<android/neuralnetworks.h>) 为应用提供适用于设备上机器学习操作的硬件加速功能。此 API 支持在设备上创建、编译和执行模型。应用通常不会直接使用 NNAPI;相反,API 将通过机器学习库、框架和工具调用,让开发者在 Android 设备上训练并部署其模型。如需了解详细信息,请参阅神经网络 API 开发者指南API 参考