本机库的命名空间

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 库的列表。

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

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

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

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