什么是原生库架构?

Absinthe ... 2024-9-22 About 3 min

# 什么是原生库架构?

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

# Android 中 ABI 的概念

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

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

主流的ABI架构:

  • armeabi-v7a: 第 7 代及以上的 ARM 处理器。2011 年以后生产的大部分 Android 设备都使用此架构
  • arm64-v8a: 第 8 代、64 位 ARM 处理器,近些年生产的 Android 设备通常是此架构
  • armeabi: 第 5 代、第 6 代的 ARM 处理器,早期的手机一般是此架构
  • x86: 平板、模拟器一般是此架构
  • x86_64: 64 位的平板或模拟器使用此架构

# 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 位不够积极?

# 我认为有以下几点原因:

  • 64 位 so 文件较大: 通常 64 位的 so 文件会比 32 位的大一些,而且目前只有 Google Play 和 AppGallery Connect 支持 aab 格式的安装包分发(即 App Bundles),而在全球的软件市场中,App 的体积都是与下载量呈负相关的
  • 上游 SDK 未提供 64 位版本: 由于 APK 中每种架构都必须提供全部的 so 库,因此 App 中只要有一个 SDK 没有提供 64 位版本,则其他 so 都无法替换为 64 位版本
Last update: 2024年9月22日 06:19
Contributors: dependabot[bot]