内容简介:追逐,探索,永不停歇~还记得刚入坑 Flutter 打包时,被深深震惊了一番,卧槽,这包好大!
追逐,探索,永不停歇~
前言
还记得刚入坑 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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- ReactNative字体大小不随系统字体大小变化而变化
- JVM 参数最佳实践:元空间的初始大小和最大大小
- 原 荐 java计算对象占用内存大小:lucene专用于计算堆内存占用大小的工具类
- 获取网络图片的大小
- 获取网络图片的大小
- 减小APK大小
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
程序员2010精华本
程序员杂志社 / 电子工业 / 2011-1 / 49.00元
《程序员(2010精华本)》主要内容:《程序员》创刊10年来,每年末编辑部精心打造的“合订本”已经形成一个品牌,得到广大读者的认可和喜爱。今年,《程序员》杂志内容再次进行了优化整合,除了每期推出的一个大型专题策划,各版块也纷纷以专题、策划的形式,将每月的重点进行了整合,让内容非常具有凝聚力,如专题篇、人物篇、实践篇等。另外杂志的版式、色彩方面也有了很大的飞跃,给读者带来耳目一新的阅读体验。一起来看看 《程序员2010精华本》 这本书的介绍吧!