Android SDK ABI 兼容策略

Android 开发 SDK 时应该注意的关于 ABI 的兼容策略

参考

https://www.jianshu.com/p/d2119b3880d8
https://developer.android.google.cn/ndk/guides/abis

ABI

ABI 是 Application binary interface,应用程序二进制接口的缩写.

不同的 Android 手机使用不同的 CPU,进而支持不同的指令集。 CPU 与指令集的每种组合都有专属的应用二进制界面,即 ABI。 ABI 可以非常精确地定义应用的机器代码在运行时如何与系统交互。 您必须为应用要使用的每个 CPU 架构指定 ABI。

ABI 的指定是在代码的编译阶段进行的,我们使用的各种静态库、动态库,就是支持某个 ABI 的。所以我们在集成很多第三方库的时候,教程会让我们把 so 放到指定的文件夹中,文件夹命名其实就是 ABI 的名字。

比如高德地图:

“使用自定义配置,将下载文件的 armeabi 文件夹复制到 libs 目录,如果有这个目录,请将下载的 so 库复制到这个目录”

Android 支持的 ABI 如下表:

在 Android Studio 里可以通过下面的配置设置工程支持的 ABI:

ndk {
    // 设置支持的SO库架构
    abiFilters 'armeabi-v7a','armeabi', 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
}

主流的ABI架构

  1. armeabi: 第5代、第6代的ARM处理器,早期的手机用的比较多。
  2. armeabi-v7a: 第7代及以上的 ARM 处理器。2011年以后的生产的大部分Android设备都使用它。
  3. arm64-v8a: 第8代、64位ARM处理器,很少设备,三星 Galaxy S6是其中之一。
  4. x86: 平板、模拟器用得比较多。
  5. x86_64: 64位的平板。

ABI 兼容策略

正常来讲,我们应该为每种 ABI 提供对应的 so 文件,但是实际场景中往往没有这么做,原因一般有以下几点:

  1. 项目体积会比较大。
  2. 库的源码往往不是自己维护的,所以有些库,没有某种 ABI 下的文件。(使用了很多 C++ 库的情况常见)
  3. 硬件和 Rom 是自己定制的,不需要适配那么多 CPU。(Android 智能设备常见这种情况)

如果我们不能够为所有架构都提供所有对应的 so,兼容工作就十分重要了。在做 SDK 开发的时候,由于 SDK 支持的 ABI 和 宿主工程支持的 ABI 可能有多种组合,所以尤其要搞明白 ABI 是如何工作的

重要原则:

  1. CPU 大都像前兼容,比如 ARMv7 的 CPU 除了支持 armeabi-v7a,也支持 armeabi,ARMv8 的 CPU 支持 armeabi,armeabi-v7a,arm64-v8a 三种 ABI。
  2. 系统优先选择对应 ABI 文件夹下的 so,比如 ARMv7 的设备,会优先选择 armeabi-v7a 下的 so 进行加载。如果文件夹存在,且 so 存在,则正常加载;如果了文件夹存在,so不存在,则运行时崩溃;如果文件夹不存在,则会去 armeabi 文件夹下找 so。具体流程用下面流程图表示:
  3. 使用了兼容的 so ,虽然一般不会出现 Crash,但是可能有性能损失。
  4. 对于每个 ABI 下的so,要么全部支持,要不都不支持。

把一些 case 汇总到表格:

可以看到,如果 SDK 支持 armeabi、armeabi-v7a、arm64-v8a 的话,几乎可以覆盖全部场景,Android 手机助手也正是采用了表格中的第4行的情形,因为一些库没有 armeabi 架构的支持包,所以最终使用了这种方式。

posted @ 2019-04-09 16:30  张驰小方块  阅读(3207)  评论(0编辑  收藏  举报