共计 8234 个字符,预计需要花费 21 分钟才能阅读完成。
追赶,摸索,永不停歇~
前言
还记得刚入坑 Flutter 打包时,被深深震惊了一番,卧槽,这包好大!
- ✓ Built build/app/outputs/apk/release/app-release.apk (23.8MB).
足足将近 24 MB,第一反馈真的懵逼了。
当然间接提交市场后,也是被人各种 diss,起因还是没什么性能,包贼大,用户下载贼不难受。
强烈要求优化 Apk 大小。
既然是摸索,前提我还是个刚入 Flutter 坑的小白白,所以嘛,不免不全面,欢送各位大佬拍砖、指导~
摸索之路 一部曲
首先,我首次打包的形式如下:
雷同应用上面的命令(默认带有 –release):
- flutter build apk
一、熊猫压缩法(缩小 0.7 MB)
首先第一想法,图片我没做压缩,同样通过查看后,发现图片在 apk 占比为 4.1%:
- 2.3 % Flutter 援用到的资源文件;
- 1.8% Android 启动页的背景图。
最初,咱们通过国宝之手试试最初能缩小多少?
这里别离针对 Flutter 下图片资源、Android/iOS 启动页进行压缩。
再次运行 build apk 后,实现输入如下日志:
- ✓ Built build/app/outputs/apk/release/app-release.apk (23.1MB).
再来看 Apk 中图片的占比以及升高到 1%:
最终 Apk 大小间接缩小了 0.7 MB,还是比拟爽的。
二、so 优化大法(缩小 14 MB)
做 Android 的小伙伴晓得,对于咱们这些小厂没能力搞动静下发 so 的小渣渣而言,只能默默逆向大厂 Apk,看看人家是怎么做的,而后借(抄)鉴(袭)。
针对 Flutter 打出的 Apk 包,排在第一位的便是 lib,占比 86.4%,足足有 19.6 MB:
这里看到将咱们编写的 Dart 代码转化为不同架构下的 so 库,以供原生调用(我是这么猜想的哈)。
针对不同 CPU 架构所代表含意,尤其 Flutter 打包 Apk 生成的三种 CPU 架构别离对应什么含意:
- x86_64: Intel 64 位,个别用于平板或者模拟器,反对 x86 以及 x86_64 CPU 架构设施。
- arm64-v8a: 第 8 代 64 位,蕴含 AArch32、AArch64 两个执行状态,且对应 32、64 bit,并且反对 armeabi、armeabi-v7a 以及 arm64-v8a。
- armeabi-v7a: 第 7 代 arm v7,应用硬件浮点运算,具备高级拓展性能,兼容 armeabi 以及 armeabi-v7a,而且目前大部分手机都是这个架构。
其实咱们第一次通过 flutter build apk 命令生成 apk 时,Google 这里曾经为咱们提醒了:
heliquan@Mac ~/CodePro/FlutterPro/xxx_app master ● flutter build apk
You are building a fat APK that includes binaries for android-arm, android-arm64, android-x64.
If you are deploying the app to the Play Store, it's recommended to use app bundles or split the APK to reduce the APK size.
To generate an app bundle, run:
flutter build appbundle --target-platform android-arm,android-arm64,android-x64
Learn more on: https://developer.android.com/guide/app-bundle
To split the APKs per ABI, run:
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Learn more on: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'... Done 13.8s
✓ Built build/app/outputs/apk/release/app-release.apk (23.1MB).
接下来通过以下命令进行别离打包(构建指定 CPU 架构类型 Apk 包):
- flutter build apk –target-platform android-arm,android-arm64,android-x64 –split-per-abi
这里解释下这个命令的含意:
- 首先 flutter build apk 示意以后构建 release 包;
- 前面 android-arm,android-arm64,android-x64 则是指定生成对应架构的 release 包;
- 最初的 –split-per-abi 则示意告知须要依照咱们指定的类型别离打包,如果移除则间接构建蕴含所有 CPU 架构的 Apk 包。
所以这个命令的含意就是通知编译器,我须要你为我针对我指定的三种不同架构别离生成对应的 Apk 包。
有的小伙伴就说了,你这空口无凭,没证据啊。
好,我给你运行一波~
- 验证:flutter build apk –target-platform android-arm,android-arm64,android-x64 后果
heliquan@Mac ~/CodePro/FlutterPro/xxx_app master ● flutter build apk --target-platform android-arm,android-arm64,android-x64
You are building a fat APK that includes binaries for android-arm, android-arm64, android-x64.
If you are deploying the app to the Play Store, it's recommended to use app bundles or split the APK to reduce the APK size.
To generate an app bundle, run:
flutter build appbundle --target-platform android-arm,android-arm64,android-x64
Learn more on: https://developer.android.com/guide/app-bundle
To split the APKs per ABI, run:
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Learn more on: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split
Removed unused resources: Binary resource data reduced from 817KB to 815KB: Removed 0%
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'... Done 115.8s
✓ Built build/app/outputs/apk/release/app-release.apk (23.1MB).
看见没,事实论证后果。
最初,咱们采取告知编译器为咱们生成指定 CPU 架构的 Apk 的形式,并查看对应输入日志信息:
heliquan@Mac ~/CodePro/FlutterPro/xxx_app master ● flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Removed unused resources: Binary resource data reduced from 816KB to 814KB: Removed 0%
Removed unused resources: Binary resource data reduced from 816KB to 814KB: Removed 0%
Removed unused resources: Binary resource data reduced from 816KB to 814KB: Removed 0%
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'... Done 36.0s
✓ Built build/app/outputs/apk/release/app-armeabi-v7a-release.apk (9.8MB).
✓ Built build/app/outputs/apk/release/app-arm64-v8a-release.apk (10.1MB).
✓ Built build/app/outputs/apk/release/app-x86_64-release.apk (10.2MB).
看看 app-armeabi-v7a-release.apk 包大小,后果是不是贼喜人?由 23.8 MB 间接缩小到 9.8 MB。
随后咱们看下对应的 apk 内容:
lib 占比也从原来的 86.4%,19.6 MB 间接缩小为 67.2%,大小 6.3 MB。
三、混同大法好(缩小 0.4 MB)
还记得 Android 混同的魅力吗?
- 减少逆向难度;
- 缩小 Apk 大小;
- 。。。
对此 Flutter 也为咱们提供了混同命令:
- flutter build apk –obfuscate –split-debug-info=/<project-name>/<directory>
简略说下我集体对于此命令的了解:
- –obfuscate:开启混同操作;
- –split-debug-info=:将因混同生成的 map 符号表缓存到此地位。
这里咱们先测试下,间接构建完整包,并增加混同操作,输入的 apk 大小有多少:
heliquan@Mac ~/CodePro/FlutterPro/xxx_app master ● flutter build apk --obfuscate --split-debug-info=HLQ_Struggle
You are building a fat APK that includes binaries for android-arm, android-arm64, android-x64.
If you are deploying the app to the Play Store, it's recommended to use app bundles or split the APK to reduce the APK size.
To generate an app bundle, run:
flutter build appbundle --target-platform android-arm,android-arm64,android-x64
Learn more on: https://developer.android.com/guide/app-bundle
To split the APKs per ABI, run:
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Learn more on: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'... Done 60.3s
✓ Built build/app/outputs/apk/release/app-release.apk (21.9MB).
同样也在我的项目根目录下生成了符号文件:
相比一开始的 23.8 MB,缩小了 1.9 MB。那么咱们间接针对不同 CPU 生成对应的 Apk 并增加混同后果又是怎么呢?
➜ xxx_app git:(master) ✗ flutter build apk --obfuscate --split-debug-info=debugInfo --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'... Done 39.3s
✓ Built build/app/outputs/apk/release/app-armeabi-v7a-release.apk (9.4MB).
✓ Built build/app/outputs/apk/release/app-arm64-v8a-release.apk (9.7MB).
✓ Built build/app/outputs/apk/release/app-x86_64-release.apk (9.8MB).
未混同的 v7a 大小与开启混同相比,开启混同缩小了 0.4 MB。
还不错。
对于混同的文件,出问题怎么调试呢?
莫慌,Flutter 同样提供了 symbolize 神器,当然这个不在涉猎范畴内,就不具体解释了,晓得就好:
heliquan@Mac ~/CodePro/FlutterPro/haozhuan_app master ● flutter symbolize -h
Symbolize a stack trace from an AOT compiled flutter application.
Usage: flutter symbolize [arguments]
-h, --help Print this usage information.
-d, --debug-info=</out/android/app.arm64.symbols> A path to the symbols file generated with "--split-debug-info".
-i, --input=</crashes/stack_trace.err> A file path containing a Dart stack trace.
-o, --output=<A file path for a symbolicated stack trace to be written to.>
Run "flutter help" to see global options.
End
下面叨叨半天,总结一个比拟有用的命令:
- flutter build apk –obfuscate –split-debug-info=HLQ_Struggle –target-platform android-arm,android-arm64,android-x64 –split-per-abi
含意就是,哥,帮我针对不同 CPU 架构别离打包,别忘记混同哈,生成的符号表文件记得帮我放在 HLQ_Struggle 目录下。
具体日志如下:
heliquan@Mac ~/CodePro/FlutterPro/xxx_app master ● flutter build apk --obfuscate --split-debug-info=HLQ_Struggle --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Removed unused resources: Binary resource data reduced from 816KB to 814KB: Removed 0%
Removed unused resources: Binary resource data reduced from 816KB to 814KB: Removed 0%
Removed unused resources: Binary resource data reduced from 816KB to 814KB: Removed 0%
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'... Done 36.9s
✓ Built build/app/outputs/apk/release/app-armeabi-v7a-release.apk (9.4MB).
✓ Built build/app/outputs/apk/release/app-arm64-v8a-release.apk (9.7MB).
✓ Built build/app/outputs/apk/release/app-x86_64-release.apk (9.8MB).
当然也有小伙伴说了,打包前 clean 下,生成的包会小,理论测试一下:
heliquan@Mac ~/CodePro/FlutterPro/xxx_app master ● flutter clean
Cleaning Xcode workspace... 3.3s
Deleting build... 2,774ms (!)
Deleting .dart_tool... 41ms
Deleting Generated.xcconfig... 0ms
Deleting flutter_export_environment.sh... 0ms
Deleting App.framework... 9ms
heliquan@Mac ~/CodePro/FlutterPro/xxx_app master ● flutter build apk --obfuscate --split-debug-info=HLQ_Struggle --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Running Gradle task 'assembleRelease'... Removed unused resources: Binary resource data reduced from 816KB to 814KB: Removed 0%
Removed unused resources: Binary resource data reduced from 816KB to 814KB: Removed 0%
Removed unused resources: Binary resource data reduced from 816KB to 814KB: Removed 0%
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'... Done 215.3s (!)
✓ Built build/app/outputs/apk/release/app-armeabi-v7a-release.apk (9.4MB).
✓ Built build/app/outputs/apk/release/app-arm64-v8a-release.apk (9.7MB).
✓ Built build/app/outputs/apk/release/app-x86_64-release.apk (9.8MB).
依据以上输入后果,并没发现缩小了哪儿。
一点小经验分享,当然必定会有更好的操作方法,然而目前仅次于此,欢送各位大佬交换~
Thanks
- 熊猫压缩法
- Flutter apk 最简略的瘦身形式
- Android ABI
- Build an APK
- 混同 Dart 代码
- 测量你的利用体积
- Flutter apps are too big in size
- Build and release an Android app
- How to decrease the size of app.framework on iOS? #21813:看得我各种懵