本机库的命名空间

Android 7.0 引入了本机库的命名空间,以限制内部 API 可见性并解决应用程序意外使用平台库而不是自己的库的情况。有关特定于应用程序的更改,请参阅在 Android 7.0 Android 开发人员博客文章中使用私有 C/C++ 符号限制提高稳定性

建筑学

在 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 开始,供应商公共库具有以下附加限制和所需设置:

  1. 供应商中的本机库必须正确标记,以便应用程序可以访问它。如果任何应用程序(包括第三方应用程序)需要访问,则该库必须在特定于供应商的file_contexts文件中标记为same_process_hal_file ,如下所示:
    /vendor/lib(64)?/libnative.so u:object_r:same_process_hal_file:s0
    ,其中libnative.so是本机库的名称。
  2. 该库无论是直接还是通过其依赖项传递,都不得依赖于除 VNDK-SP 和 LLNDK 库之外的系统库。在development/vndk/tools/definition/tool/datasets/eligible-list-<version>-release.csv中找到 VNDK-SP 和 LLNDK 库的列表。

从 Android 15(AOSP 实验性)开始,供应商公共库可以放入供应商 APEX中。当打包在供应商 APEX 中时,在 APEX 清单的provideNativeLibs属性中列出库。

更新应用程序以不使用非公共本机库

仅针对 SDK 版本 24 或更高版本的应用程序启用此功能;有关向后兼容性,请参阅 表 1。如果您的应用程序链接到私有本机库,会出现什么情况。 CDD 第 3.1.1 节中列出了应用程序可访问的 Android 本机库(也称为公共本机库)的列表。应更新面向 24 或更高版本并使用任何非公共库的应用程序。有关更多详细信息,请参阅链接到平台库的 NDK 应用程序

更新应用程序的本机库依赖项

面向 SDK 版本 31 (Android 12) 或更高版本的应用程序必须使用应用清单中的<uses-native-library>标记显式指定其本机共享库依赖项。如果设备上不存在所请求的库的任何部分,则不会安装该应用程序。安装应用程序后,向它们提供它们请求的本机共享库。这意味着应用程序无法访问未出现在应用程序清单中的本机共享库。