| <html devsite><head> |
| <title>原生库的命名空间</title> |
| <meta name="project_path" value="/_project.yaml"/> |
| <meta name="book_path" value="/_book.yaml"/> |
| </head> |
| <body> |
| <!-- |
| Copyright 2017 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <p> |
| Android 7.0 推出了针对原生库的命名空间,旨在限制内部 API 可见性,并解决应用在使用平台库(而非它们自己的库)时意外终止的问题。请参阅<a href="http://android-developers.blogspot.com/2016/06/improving-stability-with-private-cc.html">通过 Android 7.0 中的私有 C/C++ 符号限制提升稳定性</a>这篇 Android 开发者博文,了解针对应用的更改。</p> |
| |
| <h2 id="architecture">架构</h2> |
| |
| <p> |
| 这项更改会将系统库与应用库分离开来,从而很大程度上避免意外使用内部系统库(反之亦然)。 |
| </p> |
| |
| <img src="images/namespace-libraries.png" alt="原生库的命名空间" id="namespace-libraries"/> |
| <p class="img-caption"> |
| <strong>图 1.</strong> 原生库的命名空间 |
| </p> |
| |
| <p> |
| 原生库的命名空间可防止应用使用私有平台的原生 API(例如使用 OpenSSL)。它还可以避免应用在使用平台库(而非它们自己的库)时出现意外终止的情况(如使用 <code>libpng</code> 时)。 |
| </p> |
| |
| <h2 id="adding-additional-native-libraries">添加其他原生库</h2> |
| |
| <p> |
| 除了标准的公共原生库之外,芯片供应商(从 Android 7.0 起)和设备制造商(从 Android 9 起)还可以选择提供可供应用访问的其他原生库,方法是将它们放在相应的库文件夹中,并在 .txt 文件中明确列出它们。 |
| </p> |
| |
| <p>库文件夹是:</p> |
| <ul> |
| <li><code>/vendor/lib</code>(对于芯片供应商的 32 位库)和 <code>/vendor/lib64</code>(对于芯片供应商的 64 位库)</li> |
| <li><code>/system/lib</code>(对于设备制造商的 32 位库)和 <code>/system/lib64</code>(对于设备制造商的 64 位库)</li> |
| </ul> |
| |
| <p>.txt 文件是:</p> |
| <ul> |
| <li><code>/vendor/etc/public.libraries.txt</code>(对于芯片供应商的库)</li> |
| <li><code>/system/etc/public.libraries-COMPANYNAME.txt</code>(对于设备制造商的库),其中 <code>COMPANYNAME</code> 指的是制造商的名称(例如 <code>awesome.company</code>)。<code>COMPANYNAME</code> 应该匹配 <code>[A-Za-z0-9_.-]+</code>; 字母数字字符、_、.(点)和 -。如果某些库来自外部解决方案提供商,则可以在设备中包含多个此类 .txt 文件。 |
| </li></ul> |
| |
| <p> |
| <strong>必须</strong>将 <code>system</code> 分区内由设备制造商公开的原生库命名为 <code>lib*COMPANYNAME.so</code>,例如 <code>libFoo.awesome.company.so</code>。换句话说,没有公司名称后缀的 <code>libFoo.so</code> 不得公开。库文件名中的 <code>COMPANYNAME</code> 必须与列出库名称的 txt 文件的名称中的 <code>COMPANYNAME</code> 匹配。 |
| </p> |
| |
| <p> |
| 作为 AOSP 一部分的原生库不得公开(默认情况下公开的标准公共原生库除外)。只有芯片供应商或设备制造商添加的其他库可供应用访问。 |
| </p> |
| |
| <p> |
| 从 Android 8.0 开始,供应商的公共库需要遵循以下额外限制,并需要进行设置: |
| </p> |
| |
| <ol> |
| <li>供应商的原生库必须添加适当的标签,以供应用访问。如有任何应用(包括第三方应用)要求访问原生库,则该库必须在供应商特定的 <code>file_contexts</code> 文件中标记为 <code>same_process_hal_file</code>,具体如下所示: |
| <pre class="devsite-click-to-copy">/vendor/lib(64)?/libnative.so u:object_r:same_process_hal_file:s0</pre> |
| 其中,<code>libnative.so</code> 为原生库的名称。 |
| </li> |
| <li>库不得依赖(无论是直接依赖,还是通过其依赖项间接依赖)VNDK-SP 库和 LLNDK 库之外的任何系统库。您可以在 <code>development/vndk/tools/definition/tool/datasets/eligible-list-<version>-release.csv</code> 中找到 VNDK-SP 库和 LLNDK 库的列表。 |
| </li> |
| </ol> |
| |
| <h2 id="updating-app-non-public">将应用更新为不使用非公共原生库</h2> |
| |
| <p> |
| 仅针对 SDK 版本为 24 或更高版本的应用启用此功能;要了解向后兼容性,请参阅<a href="http://android-developers.blogspot.com/2016/06/improving-stability-with-private-cc.html">表 1. 当应用关联到私有原生库时会发生什么情况</a>。可供应用访问的 Android 原生库(又称为公共原生库)列表列于 CDD 部分 3.1.1。适用于版本 24 或更高版本且使用任何非公共库的应用应进行更新。要了解详情,请参阅<a href="https://developer.android.com/preview/behavior-changes.html#ndk">关联到平台库的 NDK 应用</a>。 |
| </p> |
| |
| </body></html> |