Andriod:So库适配简单总结

前言

日常开发我们经常会使用到第三库,涉及到底层的语音,视频等都需要添加so库。
而so库的体积一般来说非常的大,不搞清楚随意添加会导致apk体积暴增。
本文只做一个简单的学习总结。强烈建议阅读文章:
为何大厂APP如微信、支付宝等只适配了armeabi-v7a/armeabi?

CPU架构

Android目前支持以下7种ABIs(Application Binary Interface的缩写,即应用二进制接口):

mips, mips64, X86, X86–64, arm64-v8a, armeabi, armeabi-v7a
CPU架构 描述 市场占有
arm64-v8a 第8代ARM,64位 目前主流版本
armeabi-v7a 第7代ARM,32位 一些老旧手机
armeabi 第5代ARM,32位,NDK r17不再支持 极少,可忽略
x86_64/X86 intel,64位/32位,可兼容arm的so库 1%以下
mips64/mips NDK r17不再支持 极少用于手机,可以忽略

x86_64/X86:架构的手机都会包含由Intel提供的称为Houdini的指令集动态转码工具实现对arm.so的兼容,再考虑x86 1%以下的市场占有率,x86 相关的两个 .so 也是可以忽略的。

如何选择?

我们来看一下大厂App如何选择so库:

App cpu
微信 arm64-v8a
支付宝 armeabi
QQ armeabi
手机淘宝 armeabi-v7a

值得一提的是,这4大App都只适配了一种Cpu架构。

上面这些APP只适配了一种CPU架构,比如只适配了armeabi-v7a,那如果APP装在其他架构的手机上,如arm64-v8a上,会崩溃吗?

答案是不会的。
因为armeabi-v7a和arm64-v8a会向下兼容:
只适配armeabi的APP可以跑在armeabi,x86,x86_64,armewabi-v7a,arm64-v8上
只适配armeabi-v7a可以运行在armeabi-v7a和arm64-v8a
只适配arm64-v8a 可以运行在arm64-v8a上

当然这会损失一些性能。见下图,你就明白了:

640.png

适配方案

综合上面市场占有及大厂适配方案来看,我们只需要适配arm架构即可,即armeabi,armewabi-v7a,arm64-v8三选一。

1.方案一:只适配armeabi

优点:基本上适配了全部CPU架构(除了淘汰的mips和mips_64)
缺点:性能低,相当于在绝大多数手机上都是需要辅助ABI或动态转码来兼容

2.方案二:只适配armeabi-v7a

同理方案一,只是又筛掉了一部分老旧设备,在性能和兼容二者中比较平衡

3.方案三: 只适配arm64-v8

优点: 性能最佳
缺点:只能运行在arm64-v8上,要放弃部分老旧设备用户

Google Play 从2019年8月开始,就强制APP适配arm64-v8a,以慢慢淘汰32位的armeabi-v7a。
所以全面适配arm64-v8是迟早的事,因此新项目建议提前适配arm64-v8。

如果我们既不想放弃旧设备用户,也要保证性能,就只能牺牲apk的体积为代价:

ndk {
            abiFilters "armeabi", "arm64-v8a"
        }

使用abiFilters,就能指定app打中包含哪些Cpu架构的so库,不指定的则被忽略。

注意事项

需要注意的是,虽然ABI加载So会向下兼容。但是如果你的App同时存在两种架构如:"armeabi", "arm64-v8a"。  
那么不同Cpu架构的手机便只会加载对应的SO库不再向下兼容。
比如a.so存在armeabi中,不存在arm64-v8a中。那么arm64-v8a手机加载a.so库时,便会崩溃。  
因此需要每个So库同时添加到每种架构中。
armeabi-v7a与armeabi都适用于32位CPU架构,因此理论上他们的So库时完全通用的,即如果你的项目只适配了armeabi架构,
但是第三方框架只提供了armeabi-v7a的So库,也是可以直接用的。但是arm64-v8a是64位的,所以无法通用。
一些没人维护的第三方库,年久失修,可能没有arm64-v8a架构的So库。
我们这个时候就要考虑是否适配arm64-v8a架构,或者使用其他库代替。  

番外篇--性能+兼容能否兼得?

除了适配所有全部CPU架构外,就特么不能性能和兼容同时兼得吗?其实Google早有考虑。

可以实现的那就是 abi split,分包,实现也很简单,在gradle 中添加如下配置:

 android {
      ...
      splits {

        // Configures multiple APKs based on ABI.
        abi {

          // Enables building multiple APKs per ABI.
          enable true

          // By default all ABIs are included, so use reset() and include to specify that we only
          // want APKs for x86 and x86_64.

          // Resets the list of ABIs that Gradle should create APKs for to none.
          reset()

          // Specifies a list of ABIs that Gradle should create APKs for.
          include "x86", "x86_64", "arm64-v8a", "armeabi", "armeabi-v7a"

          // Specifies that we do not want to also generate a universal APK that includes all ABIs.
          universalApk false
        }
      }
    }

就能为每个CPU架构单独打一个APK,该apk中就只包含一个架构。

这样,又能保证性能,又能不额外增加APK的大小,同时又又很完美的兼容,因为可以为所有架构都单独打一个包,一举多得。

Google Play 支持上传多个不同平台的APK,这样,就能根据不同的CPU架构,下载不同的包。

但是,很遗憾,国内的应用商店目前还不支持!因此看看就好 23333

参考

https://mp.weixin.qq.com/s/jnZpgaRFQT5ULk9tHWMAGg

你可能感兴趣的:(Andriod:So库适配简单总结)