APK Shrink探索--(一)SO方面

背景与问题

随着客户端接入业务的日益增加和集成功能的日益丰富,客户端APK安装包也随之增大。
过大的安装包会带来的不利影响如下:
1.对外,增加用户下载时的流量消耗,延长应用安装时间,降低用户体验。
2.对内,增加了企业“打包-上线-发布”流程消耗的时间成本,同时也会影响到开发时的单次构建效率。

解决方案

APK瘦身

利用AS对APK包进行分析,结果如图:
这里写图片描述

由图可知,APK大小中占比重较大的主要为lib,resource(res,assets),dex,因此APK瘦身主要针对这三者进行处理。本篇就先从lib入手。

1. lib目录优化分析
由图可知,当前lib目录下包含armeabi、armeabi-v7a,x86三个子目录,它们分别代表三种ABI,并包含支持该ABI的so库文件。
查看三个子目录,发现三个ABI目录下包含同名so文件,armeabi-v7a额外包含一些so文件,那么,这些同名so文件是否可以只保留一份?如何选择?
同时,对支付宝、微信等大厂的APK进行解包可以看到,可以看到这些大厂的APK中,lib目录下是只保留一份armeabi的。

2.Android SO与ABI
ABI简介

  • Android设备可支持ARMv5,ARMv7,X86,ARMv8,X86_64等多种CPU架构
  • 每种CPU架构都定义一种 ABI(Application Binary Interface,应用二进制接口),ABI定义了其所对应的CPU架构能够执行的二进制文件(如.so文件)的格式规范。
CPUARMv5ARMv7x86MIPSARMv8MIPS64x86_64
ABIarmeabiarmeabi-v7ax86mipsarmeabi-v8amips64x86-64

SO简介

  • so(shared object,共享库)是机器可以直接运行的二进制代码,是Android上的动态链接库,类似于Windows上的dll.
  • 每一个Android应用所支持的ABI是由其APK提供的.so文件决定的. 例如:
    lib
    |
    ├── armeabi
    │ └── libmath.so
    ├── armeabi-v7a
    │ └── libmath.so
    ├── mips
    │ └── libmath.so
    └── x86
    └── libmath.so

    说明该应用所支持的ABI为armeabi, armeabi-v7a, mips, 和x86。

Android系统的ABI支持

  • Android可以在运行期间确定当前系统所支持的ABI,这是由系统编译时的具体参数指定的:
    primary ABI(主ABI):对应当前系统中使用的机器码类型
    secondary ABI(副ABI):表示当前系统支持的其他ABI类型
    这里写图片描述
    上图可知,该设备的primary ABI是arm64-v8a

  • 许多手机支持不止一个ABI,比如,一个基于ARMv7的设备会将armeabi-v7a定义为primary ABI,armeabi作为secondary ABI,意味着这台机器同时支持armeabi-v7a和armeabi

  • X86手机存在一个Binary Translator(二进制转换中间层) houdini. 它会在运行期间动态的读取arm指令并将之转换为x86指令去执行。
  • 许多基于x86的设备也可以运行armeabi-v7a和armeabi的so,对于这些机器,primary ABI是x86,secondary ABI则是armeabi-v7a.

APK安装时对so的选择过程

  • 应用安装时,Package Manager会扫描整个apk文件,寻找符合下面文件路径格式的动态链接库:
    lib//lib.so

  • 如果在apk内并没有找到适合当前机器primary-abi的so,Package Manager会尝试寻找适合secondary-abi的so文件: lib//lib.so

  • 如果找到了合适的so文件,包管理器会将该ABI文件夹下所有so库全部拷贝至应用的data目录下: data/data//lib/

  • 运行时找不到so,则会报Java.lang.UnsatisfiedLinkError问题
  • 安装APK时PMS只负责拷so,至于这个so是何种ABI是不感知的。
  • 支持armeabi-v7a的设备同样支持armeabi的so文件,反之不行。

3.SO精简处理方案
通过对使用用户中各ABI的分布对比,armeabi和x86占比极小,所以选择不考虑保留armeabi和x86,只保留armeabi-v7a。
通过修改gradle文件,在buildType模块增加对打包时ABI的指定,如下:

ndk {
    abiFilters "armeabi"        
    }

经过so的精简,APK大小减小了7M+,下一步会继续研究下对资源文件和dex文件的精简。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值