其中,<abi>
是[支持的 ABI](() 下列出的 ABI 名称之一,<name>
是您为 [Android.mk
](() 文件中的 LOCAL_MODULE
变量定义库时使用的库名称。由于 APK 文件只是 zip 文件,因此打开它们并确认共享原生库位于该位于的位置很简单。
如果系统在预期位置找不到原生共享库,便无法使用它们。在这种情况下,应用本身必须复制这些库,然后执行 dlopen()
。
在胖 APK 中,每个库位于名称与相应 ABI 匹配的目录下。例如,胖 APK 可能包含:
/lib/armeabi/libfoo.so
/lib/armeabi-v7a/libfoo.so
/lib/arm64-v8a/libfoo.so
/lib/x86/libfoo.so
/lib/x86_64/libfoo.so
注意:搭载 4.0.3 或更早版本、基于 ARMv7 的 Andro 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》无偿开源 徽信搜索公众号【编程进阶路】 id 设备从 armeabi
目录(而非 armeabi-v7a
目录,如果两个目录都存在)安装原生库。这是因为在 APK 中,/lib/armeabi/
在 /lib/armeabi-v7a/
后面。从 4.0.4 开始,此问题已修复。
Android 平台 ABI 支持
Android 系统在运行时知道它支持哪些 ABI,因为版本特定的系统属性会指示:
-
设备的主要 ABI,与系统映像本身使用的机器代码对应。
-
(可选)与系统映像也支持的其他 ABI 对应的辅助 ABI。
此机制确保系统在安装时从软件包提取最佳机器代码。
为实现最佳性能,应直接针对主要 ABI 进行编译。例如,基于 ARMv5TE 的典型设备只会定义主要 ABI:armeabi
。相反,基于 ARMv7 的典型设备将主要 ABI 定义为 armeabi-v7a
,并将辅助 ABI 定义为 armeabi
,因为它可以运行为每个 ABI 生成的应用原生二进制文件。
64 位设备也支持其 32 位变体。以 arm64-v8a 设备为例,该设备也可以运行 armeabi 和 armeabi-v7a 代码。但请注意,如果应用以 arm64-v8a 为目标,而非依赖于运行 armeabi-v7a 版应用的设备,应用在 64 位设备上的性能要好得多。
许多基于 x86 的设备也可运行 armeabi-v7a
和 armeabi
NDK 二进制文件。对于这些设备,主要 ABI 将是 x86
,辅助 ABI 是 armeabi-v7a
。
安装时自动解压缩原生代码
安装应用时,软件包管理器服务将扫描 APK,并查找以下形式的任何共享库:
lib//lib.so
如果未找到,并且您已定义辅助 ABI,该服务将扫描以下形式的共享库:
lib//lib.so
找到所需的库时,软件包管理器会将它们复制到应用的 data
目录 (data/data/<package_name>/lib/
) 下的 /lib/lib<name>.so
。
如果根本没有共享对象文件,应用也会编译并安装,但在运行时会崩溃。