首先需要了解 Flutter 编译 APP 时的三种构建模式:
-
Debug
-
Release
-
Profile
在将每种构建模式的构建方法。
1. Debug
Debug 模式,顾名思义,就是在开发调试时使用的模式。在 Debug 模式下,为了方便调试,Flutter 增加了很多方便调试的功能:
-
Flutter 的断言(Assertions)功能是开的
-
Flutter 的 Dart Observatory 是开的,Dart Observatory 是用于分析和调试 Dart 代码的工具,可以 debugger,也可以检测性能等,后面会详细介绍 Dart Observatory 的使用。
-
Flutter 的一些扩展功能是开启的,例如监控性能的浮层等。
-
Dart 代码采用 JIT 编译,因此可以使用 Hot Reload,方便快速开发。
可以看到,在 Debug 模式下,一方面 Flutter 采用的是 JIT 编译,另一方面 开启了很多额外功能,因此性能会差一些,所以 Debug 模式只能用在开发阶段。
当 Flutter APP 已 Debug 模式运行时, 既可以运行在真机上,也可以运行在模拟器上。
Debug 构建方法
-
IDE
- Android Stuido:
-
点击 Debug > Start Debugging 或 Debug > Start Without Debugging。
命令行:
$flutter run
2. Release
Release 模式,顾名思义,就是在发布 APP 时使用的模式。使用 Release 模式部署应用程序,可以达到最高的性能和最小的安装包大小。
在 Release 模式下,为了提高运行性能:
-
断言(Assertions)功能关闭
-
没有 Debugging 的信息
-
Debugging 的功能关闭
-
Dart 代码采用 AOT 编译。使用 AOT 编译成 Native Arm Code,不仅可以使 Flutter APP 因更快速的启动,更快速的执行,而且使用 AOT 编译生成的 Native Arm Code 的产物的大小也会小很多。
-
一些扩展功能被关闭
-
所以,当你的 APP 要发布的时候,一定要使用 Release 模式。
Release 模式只能运行在真机上,不能运行在模拟器上。
Release 构建方法
- 要想构建 Release 包,首先得连接真机,因为 Release 模式只能运行在真机上。
IDE
Android Studio
打开 Edit Configurations...,如下图:
在 Additional arguments 这里加上
--release
,构建出来的就是 Release 模式,为空的话,就是 Debug 模式。或者,直接运行 Run -> Flutter Run 'main.dart' in Release Mode
-
用命令行:
$flutter run --release
或者
$flutter build apk //构建Android Release包
$flutter build ios //构建iOS Release包
如果你没有连真机,而是连的模拟器,则会报如下的错误:
3. Profile
Profile 模式是专门监控性能的模式,在 Debug 模式下,开启了很多额外的功能,因此不能实际反应应用的性能,但在 Release 模式下,也没有监控的功能,所以就有了 Profile 模式。Profile 模式是 Debug 模式和 Release 模式的结合。
Profile 模式和 Release 模式更接近,都采用了 AOT 编译,所以都不能用 Hot Reload,但是 Profile 相对于 Release,保留了一定的调试能力,足以分析 Flutter 的性能:
-
一些扩展的服务功能是打开的,例如监控性能的浮层等。
-
Tracing 是打开的,而且 Dart Observatory 也可以连接到进程。
而且为了更加准确的反应 Flutter 在真机上的运行性能,Profile 模式只能跑在真机上,不能运行在模拟器上。
Profile 构建方法
- 要想构建 Profile 包,首先得连接真机,因为 Profile 模式只能运行在真机上。
IDE
Android Studio
按照 Release 的方法,这里参数改为
--profile
或者,直接运行 Run -> Flutter Run 'main.dart' in Profile Mode
VS Code
选择 Debug ,点击 Open Configurations,打开 launch.json,如下:
增加下面这一行:
"flutterMode": "profile"
完整的 launch.json 为:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
}
]
}
然后在点击 Debug > Start Without Debugging。
-
用命令行:
$flutter run --profile
Flutter Android/iOS 安装包分析
Flutter Android Debug 安装包分析
如果前面你连接了 Android 虚拟机或真机,并且按照前面几节的操作运行了 Flutter APP,那么在 Flutter 目录下,找到
build/app/outputs/apk/debug/app-debug.apk
,就是 Android 的 Debug 安装包,安装包里的内容如下图:
lib目录下的 Flutter Engine so
lib 目录下是 Flutter Engine的so:
-
-
总共有三个平台的 so:x86_64
-
x86
-
arm64-v8a
- so 的大小问题
总大小是17.8M,占到整个apk安装包的71.4%,你可能会觉得好大,但是不用担心,因为Debug模式需要运行在模拟器上,所以才打入了x86_64和x86两个平台的so,所以会比较大,在Release模式下是不会打入x86_64和x86的,而且Google也在不断优化Flutter Engine的so大小。
- assets 目录
assets 目录下的都是 Flutter 生成的产物。
-
flutter_assets 目录
-
kernel_blob.bin:由Flutter代码生成
-
vm_snapshot_data:VM虚拟机数据段
-
isolate_snapshot_data:应用程序数据段
-
fonts:字体库
-
packages:Flutter资源库
-
FontManifest.json:字体的Manifest
-
AssetManifest.json:资源的Manifest
-
-
flutter_shared 目录
icudtl.dat:该文件的作用是告诉Flutter如何使用unicode进行国际文本处理,用于国际化的。
classes.dex
Flutter 的 Android 代码编译成的 classes.dex。
res 目录
Flutter 的 Android 工程的资源文件。
Flutter Android Release 安装包分析
连接了 Android 真机,构建 Release 模式,在 Flutter 目录下,找到
build/app/outputs/apk/release/app-release.apk
,就是 Android 的 Release 安装包,安装包里的内容如下图:
lib 目录下的 Flutter Engine so
lib 目录下是 Flutter Engine 的 so:
总共有两个平台的 so:
-
arm64-v8a
-
armeabi-v7a
大小问题:
总大小是 5.9M ,占到整个 apk 安装包的 75.3%,如果想要继续优化 so 的大小,可以只用 areabi-v7a 的 so。
assets 目录
assets 目录下的都是 Flutter 生成的产物。
-
isolate_snapshot_data:应用程序数据段
-
isolate_snapshot_instr: 应用程序指令段
-
vm_snapshot_data:VM虚拟机数据段
-
vm_snapshot_data: VM虚拟机数据段
-
flutter_assets 目录
-
fonts:字体库
-
packages:Flutter资源库
-
FontManifest.json:字体的Manifest
-
AssetManifest.json:资源的Manifest
-
-
flutter_shared 目录
icudtl.dat:该文件的作用是告诉Flutter如何使用unicode进行国际文本处理,用于国际化的。
classes.dex
Flutter 的 Android 代码编译成的 classes.dex。
res 目录
Flutter 的 Android 工程的资源文件。
Flutter iOS Debug 安装包分析
如果前面你连接了 iOS 模拟器或真机,并且按照前面几节的操作运行了 Flutter APP,那么在 Flutter 目录下,找到
build/Debug-iphonesimulator/Runner
或者
build/iphonesimulator/Runner
,就是 iOS 的 Debug 安装包,安装包里的内容如下图:
-
Frameworks 目录
Frameworks 目录下的 framework 有:
App.frmework
-
-
Flutter 的 iOS 代码编译成的 framework。用 file 命令查看 App.frmework 支持的架构:
$ file Runner.app/Frameworks/App.framework/App Runner.app/Frameworks/App.framework/App: Mach-O 64-bit dynamically linked shared library x86_64
只支持 x86_64 一种架构。
Flutter.frmework
Flutter 的库和引擎。
用 file 命令查看 Flutter.frmework 支持的架构:
$ file Runner.app/Frameworks/Flutter.framework/Flutter
Runner.app/Frameworks/Flutter.framework/Flutter: Mach-O universal binary with 1 architecture: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64]
Runner.app/Frameworks/Flutter.framework/Flutter (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
只支持 x86_64 一种架构。
- Flutter.framework 还有 icudtl.dat
icudtl.dat:该文件的作用是告诉Flutter如何使用unicode进行国际文本处理,用于国际化的。
大小问题:
App.framework 总大小 26k,Flutter.framework 的总大小为 25.7M。Debug 模式下的大小没有参考意义,因为 Debug 不会是正式发布的包。
flutter_assets 目录
assets 目录下的都是 Flutter 生成的产物。
这里的产物是 iOS 和 Android 是一样的,只是路径有些不同。
-
kernel_blob.bin:由Flutter代码生成
-
vm_snapshot_data:VM虚拟机数据段
-
isolate_snapshot_data:应用程序数据段
-
fonts:字体库
-
packages:Flutter资源库
-
FontManifest.json:字体的Manifest
-
AssetManifest.json:资源的Manifest