Android 7.0 為原生庫引入了命名空間,以限制內部 API 可見性並解決應用意外使用平台庫而不是自己的平台庫的情況。有關特定於應用程序的更改,請參閱Android 7.0 Android 開發人員博客文章中的通過私有 C/C++ 符號限制提高穩定性。
建築學
在 Android 7.0 及更高版本中,系統庫與應用程序庫是分開的。
![本機庫的命名空間](https://source.android.google.cn/static/devices/tech/config/images/namespace-libraries.png?authuser=8&hl=zh-tw)
圖 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 庫以外的系統庫。在
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>
標記明確指定其本機共享庫依賴項。如果設備上不存在所請求庫的任何部分,則不會安裝該應用程序。安裝應用程序後,僅向它們提供它們請求的本機共享庫。這意味著應用無法訪問未出現在應用清單中的本機共享庫。