什么是原生库架构?

大家常说的 32 位 / 64 位 App 到底是什么意思?首先我们先了解几个概念:

Android 中 ABI 的概念

ABI,即 Application Binary Interface(应用程序二进制接口),其定义了一套规则,允许编译好的二进制目标代码能在所有兼容该 ABI 的操作系统中无需改动就能运行。

不同的 Android 设备使用不同的 CPU,而不同的 CPU 支持不同的指令集。CPU 与指令集的每种组合都有专属的应用二进制接口 (ABI),因此需要提供对应的二进制接口交互规则(即对应的 ABI 文件)才能进行交互。部分 CPU 能够支持多种交互规则,但这是在牺牲性能的前提下所做的兼容。

主流的ABI架构:

ABI 和 CPU 的关系

当一个 App 被安装在设备上时,只有该设备支持的 CPU 架构对应的 .so 文件会被拷贝到设备中。如果支持多个 ABI 架构,会按照优先级进行拷贝。

CPU 与 ABI 的对照关系如下:

CPU ABI
ARMv5 armeabi
ARMv7 armeabi, armeabi-v7a
ARMv8 armeabi, armeabi-v7a, arm64-v8a
ARMv9 arm64-v8a, arm64-v9a
MIPS mips
MIPS64 mips, mips64
x86 x86
x86_64 x86, x86_64,

可以看出 CPU 大都是向前兼容的,但是选择 ABI 时会按照优先级。例如 ARMv8 型的 CPU,优先选择 arm64-v8a 目录下的 .so 文件。如果存在,就不会再安装其他支持的 ABI 架构的 .so 文件;如果没有 arm64-v8a 目录,才会选择 armeabi-v7a 目录下的 .so 文件,最后才会选择 armeabi 目录下的 .so 文件。

注意

ARMv8 设备虽然能够运行 armeabi 或 armeabi-v7a 下的 so 库,但可能会造成性能损失。即我们经常说的 “64 位手机运行 32 位应用”。

为什么存在“无原生库”这一状态?

首先需要明确一点,我们查看一款 App 是 32 位或 64 位,实际上关心的是它引入的 so 库是 32 位还是 64 位。使用以 Java 编程语言或 Kotlin 编写的代码(包括任何库或 SDK),它们运行在安卓运行时(ART)之上,无需考虑架构因素。而编写原生代码(C/C++)则需要根据不同的架构编译成相应的 so 文件。因此,如果一款 App 没有引入 so 库(即没有使用原生代码编写应用),则讨论它是 32 位还是 64 位是无意义的。

为什么国内厂商对于升级 64 位不够积极?

我认为有以下几点原因: