Flutter之Android包大小分析

一、背景

空的flutter项目编译生成Android apk包其体积约50MB左右,而空的原生Android项目编译生成的Android apk包其体积仅3.6MB左右,二者相差巨大!什么原因导致这一结果呢?

基本猜测:flutter生成的Android安装包apk中包含了大量flutter基础库代码。这些基础代码以什么样的形式存在apk中的呢?

为了解决以上疑惑故对flutter的Android包进行分析对比。

二、Android包结构

Android apk包本质是一个zip压缩包,可以将apk后缀改为zip并通过解压工具得到内部文件,一般包含如下文件:

  • assets目录 存放需要打包到APK中的静态文件
  • lib目录 程序依赖的Native库
  • res目录 存放应用程序的资源
  • META-INF目录 存放应用程序签名和证书的目录
  • AndroidManifest.xml 应用程序的配置文件
  • classes.dex dex可执行文件
  • resources.arsc 资源配置文件

如原生apk包文件:


2.png

apk反编译工具

通过反编译工具可以进一步分析apk包内容,常用工具如下:

  • apktool:编译和反编译apk,从apk中提取图片和布局资源。
  • dex2jar:将可运行文件classes.dex反编译为jar源码文件。
  • jdex-gui:查看aar源码文件 。
  • apkanalyzer :Android Studio自带的apk分析工具。

三、原生APK与Flutter对比

一般apk分debug和release版本,故分别对这两种情况对比!

3.1 Debug包对比

flutter的debug apk包:
1.png
原生Android的debug apk包:
2.png
二者Debug包对比
对比.png

总体体积(下载体积为apk应用商店内包实际大小):

名称 压缩包 解压文件 下载体积
Android-app.apk 3.6MB 8.10 MB 3MB
flutter-app.apk 49.5MB 125 MB 49.2MB
diff(flutter-android) 45.9MB 116.9MB 46.2MB

通过对比发现,造成debug包体积差异过大的主要原因(解压文件对比):

  • lib下面添加了三种ABI的动态库,体积约94MB

  • assets目录下添加了一个kernel_blob.bin的二进制文件,体积约38MB

3.2 Release包对比

flutter的release apk包:包含三种ABI的.so库
release-flutter-app.png
Android的release apk包:
release-android-app.png
二者Release包对比
release-apk-对比.png

总体体积(下载体积为apk应用商店内包实际大小):

名称 压缩包 解压文件 下载体积
android-release-app.apk 3.2MB 7.4 MB 2.6MB
flutter-release-app.apk 15.7MB 35.5 MB 15.6MB
diff(flutter-android) 12.5MB 28.1MB 13.0MB

通过对比发现,造成release包体积差异过大的主要原因(解压文件对比):

  • lib下面添加了三种ABI的动态库,体积约34.1MB

  • assets目录下文件,体积约1MB

四、flutter生成不同ABI动态库的apk包

通过剔除不必要的ABI动态库.so包,从而减少apk包体积大小。

4.1 ABI简介

不同的 Android 设备使用不同的 CPU,而不同的 CPU 支持不同的指令集。CPU 与指令集的每种组合都有专属的应用二进制接口 (ABI)。 android支持的 ABI如下:

cpu架构.png
ABI 适用设备 市场占有率 适配厂家
armeabi-v7a 第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它。 一些老旧的手机 淘宝
arm64-v8a 第8代、64位ARM处理器 目前主流版本 微信
armeabi 第5代、第6代的ARM处理器,早期的手机用的比较多 较少 支付宝、手Q、旧版微信
x86 平板、模拟器用得比较多 很少
x86_64 64位的平板 很少

高版本的arm架构会兼容低版本的arm架构,一般厂商只会选定一个cpu架构进行适配,为了减少apk包大小我们可以选定armeabi-v7a或者arm64-v8a即可。

4.2 flutter打不同ABI的apk包

通过下面的命令,可以生成不同ABI的apk包,该命令默认release并开启压缩:

flutter build apk --split-per-abi

flutter-so-apk.png

包大小列表:

flutter-arm64.png
flutter-armeabi-v7a.png
flutter-x86-64.png

打包含单独ABI的release apk包平均大小6MB左右,可以有效的降低包体大小。

五、总结

初始项目的flutter打apk包情况如下:

  • debug环境:包体较大,因为没有压缩且包含多个ABI的so文件以及资源文件,包大小为50MB左右。
  • release环境:包体较小,因为开启了压缩且仅打单个CPU架构的so文件,包大小可以降低到6MB左右。

你可能感兴趣的:(Flutter之Android包大小分析)