1. 前言
flutter应用有两种调试环境:
- 纯flutter工程:整个app被flutter接管
- flutter混合模式开发,也称之为add-to-app模式。flutter作为sdk集成到App中。
这里要讲的是混合模式下的调试
2. add-to-app模式调试
flutter开发效率高其中一个原因是代码的hot reload。flutter在debug模式下会开启hot reload,代码为JIT。
纯flutter工程通过命令 flutter run命令启动app,天然支持热加载。但在混合模式下如何实现热加载呢?
有两种办法:
- app启动后,用命令flutter attach
- 使用VSCode插件
对比两者,我个人感觉VSCode插件比较方便,为什么?因为当修改代码后,第一种方法需要在命令行按下r才可以实现hot reload,而vscode插件可以实现自动hot reload,不需要额外的步骤。
2.1. flutter attach
➜ my_flutter git:(main) ✗ flutter attach
Connected devices:
iPhone13 Pro (mobile) • 00008110-000925E02146401E • ios • iOS 18.5 22F76
iPhone 16 (mobile) • 0F117065-677D-4941-B66B-99EDC4B99B0A • ios • com.apple.CoreSimulator.SimRuntime.iOS-18-5 (simulator)
No wireless devices were found.
[1]: iPhone13 Pro (00008110-000925E02146401E)
[2]: iPhone 16 (0F117065-677D-4941-B66B-99EDC4B99B0A)
Please choose one (or "q" to quit): 1
Waiting for a connection from Flutter on iPhone13 Pro...
Syncing files to device iPhone13 Pro... 6.5s
Flutter run key commands.
r Hot reload. 🔥🔥🔥
R Hot restart.
h List all available interactive commands.
c Clear the screen
q Quit (terminate the application on the device).
2.2. VSCode插件
- 安装flutter插件:官方文档。比我讲的清楚。
- debug模式启动add-to-app。
- 在vscode工程中按下command+shift+p:选择Flutter:Select Device,选择你的设备
- 在vscode工程中按下command+shift+p:选择Debug:Attach to Flutter on Device,选择你的设备
- 查看vscode提示,等待链接成功
- 修改代码实现hot reload
3. 如何实现脱机(离开xcode环境)调试
3.1. 结论
不能实现
3.2. 为什么不能实现?
Debug
模式使用的是 动态加载的 Dart 代码(JIT) ;- Flutter 引擎在启动时默认会从开发机上的 Dart VM 服务端口加载
main.dart
编译后的代码(kernel_blob.bin
等); - 脱机环境(非
flutter run
启动或非Xcode
启动)下,App 本身没有包含这些文件; - 所以在脱离 Flutter CLI 或 Xcode 的 debug 会话后启动,会找不到 Flutter 的入口代码。
4. debug包提测
4.1. 问题:
- 有些业务需要再debug模式下提测,但提交给测试工程师的debug包flutter初始化会失败。
4.2. 原因:
4.2.1. 分析
- Debug 模式的 Flutter Add-to-App 项目中,flutter module 会被编译为debug包。FlutterEngine 启动时会尝试 连接开发主机上的
flutter attach
服务,用于:
-
- 调试功能(热重载、日志打印、DevTools)
- 加载 Dart VM snapshot 等临时调试资源
- 而这些功能只有在 Xcode 启动时会设置好相关参数路径(通过环境变量或启动参数传入)
4.2.2. 所以:
- ✅ Xcode 启动时,会自动设置
--observatory-port
等参数,FlutterEngine 知道去哪找 Dart runtime - ❌ 图标点击启动时,这些参数没有传入,FlutterEngine 找不到调试环境、资源路径,导致
run
返回 NO(Dart isolate 无法启动)
4.3. 如何解决
- 思路:在debug App包中中使用flutter module的profile或release包。profile或release包不依赖xcode提供的环境。但也不能hot reload dart代码。
- 实现:可以通过设置上面提到的“environment['FLUTTER_BUILD_MODE']”环境变量,控制flutter module的编译模式
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/yidao/Documents/env/1/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/yidao/Documents/code/flutter/my_flutter"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
# debug profile release
export "FLUTTER_BUILD_MODE=release"