Android 7.0 推出了原生库的命名空间,以限制内部 API 可见性并解决应用意外使用平台库而非自有库的情况。如需了解针对应用的具体变更,请参阅 Android 7.0 中通过私有 C/C++ 符号限制提高稳定性 Android 开发者博文。
架构
在 Android 7.0 及更高版本中,系统库与应用库是分开的。

图 1. 原生库的命名空间。
原生库的命名空间可防止应用使用私有平台原生 API(就像使用 OpenSSL 时一样)。它还可以避免应用意外使用平台库而非自有库的情况(就像 libpng
那样)。应用库很难意外使用内部系统库(反之亦然)。
添加其他原生库
除了标准公共原生库之外,芯片供应商(从 Android 7.0 开始)和设备制造商(从 Android 9 开始)可以选择提供其他原生库,以便应用访问,方法是将这些库放在各自的库文件夹下,并在 .txt 文件中明确列出这些库。
库文件夹包括:
/vendor/lib
(对于 32 位)和/vendor/lib64
(对于 64 位),适用于芯片供应商提供的库/system/lib
(对于 32 位)和/system/lib64
(对于 64 位),适用于设备制造商提供的库
.txt 文件包括:
/vendor/etc/public.libraries.txt
,适用于芯片供应商提供的库/system/etc/public.libraries-COMPANYNAME.txt
,适用于设备制造商提供的库,其中COMPANYNAME
是指制造商的名称(例如awesome.company
)。COMPANYNAME
必须与[A-Za-z0-9_.-]+
(字母数字字符、_、.(点)和 -)匹配。如果某些库来自外部解决方案提供商,则设备中可以有多个此类 .txt 文件。
设备制造商公开发布在 system
分区中的原生库必须命名为 lib*COMPANYNAME.so
,例如,libFoo.awesome.company.so
。换句话说,不带公司名称后缀的 libFoo.so
不得公开发布。库文件名中的 COMPANYNAME
必须与列出库名称的 txt 文件中的 COMPANYNAME
匹配。
AOSP 的原生库不得公开发布(默认公开的标准公共原生库除外)。只有芯片供应商或设备制造商添加的附加库才能供应用访问。
从 Android 8.0 开始,供应商公共库具有以下附加限制和必需设置
- 供应商中的原生库必须正确标记,以便应用可以访问。如果任何应用(包括第三方应用)需要访问,则必须在供应商特定的
file_contexts
文件中将该库标记为same_process_hal_file
,如下所示 其中/vendor/lib(64)?/libnative.so u:object_r:same_process_hal_file:s0
libnative.so
是原生库的名称。 - 该库(直接或通过其依赖项传递)不得依赖于 VNDK-SP 和 LLNDK 库之外的系统库。VNDK-SP 和 LLNDK 库列表位于
development/vndk/tools/definition/tool/datasets/eligible-list-<version>-release.csv
。
从 Android 15 开始,供应商公共库可以放在 vendor APEX 中。当打包在 vendor APEX 中时,请在 APEX 清单中的 provideNativeLibs
属性中列出这些库。
更新应用以不使用非公共原生库
此功能仅对以 SDK 版本 24 或更高版本为目标的应用启用;为了向后兼容,请参阅表 1. 如果您的应用链接到私有原生库,会发生什么。CDD 第 3.1.1 节列出了应用可以访问的 Android 原生库列表(也称为公共原生库)。以 24 或更高版本为目标并使用任何非公共库的应用应进行更新。有关更多详细信息,请参阅链接到平台库的 NDK 应用。
更新应用以适应其原生库依赖项
以 SDK 版本 31 (Android 12) 或更高版本为目标的应用必须显式指定其原生共享库依赖项,方法是在应用清单中使用 <uses-native-library>
标记。如果设备上不存在请求的库的任何部分,则不会安装该应用。安装应用后,系统会仅向其提供它们请求的原生共享库。这意味着应用无法访问未在应用清单中显示的原生共享库。