Flutter 调试与 DevTools
本节将介绍 Flutter 的调试工具和常用调试技巧。
Flutter DevTools 简介
Flutter DevTools 是一套用于调试和分析 Flutter 应用的工具集。
启动 DevTools
$ flutter run
在运行应用后,终端会显示 DevTools 的 URL,通常是 http://127.0.0.1:9100
常用命令
| 命令 | 说明 |
|---|---|
| flutter doctor | 检查开发环境配置 |
| flutter analyze | 静态代码分析 |
| flutter test | 运行测试 |
print 和 debugPrint
实例:基本调试输出
// 基础打印
print('Hello Debug'); // 输出到控制台
// debugPrint 避免长文本截断
debugPrint('这是一段很长的文本,可以完整输出而不会被截断');
// 条件打印
if (debugMode) {
print('调试信息');
}
// 打印对象(需要 toString)
final user = {'name': '张三', 'age': 25};
print('用户信息: $user'); // 输出: 用户信息: {name: 张三, age: 25}
print('Hello Debug'); // 输出到控制台
// debugPrint 避免长文本截断
debugPrint('这是一段很长的文本,可以完整输出而不会被截断');
// 条件打印
if (debugMode) {
print('调试信息');
}
// 打印对象(需要 toString)
final user = {'name': '张三', 'age': 25};
print('用户信息: $user'); // 输出: 用户信息: {name: 张三, age: 25}
断言 - assert
断言用于在开发时检查条件,仅在调试模式下生效。
< h2 class="example">实例:使用断言
// 简单的断言
assert(user != null, '用户不能为空');
// 函数参数验证
void setAge(int age) {
// 年龄必须大于 0
assert(age > 0, '年龄必须大于 0');
this.age = age;
}
// UI 构建中的断言(仅开发时)
Widget build(BuildContext context) {
// 确保 context 不为 null
assert(context != null);
// 确保有父级 Scaffold
assert(debugCheckHasMaterial(context));
return Scaffold(...);
}
assert(user != null, '用户不能为空');
// 函数参数验证
void setAge(int age) {
// 年龄必须大于 0
assert(age > 0, '年龄必须大于 0');
this.age = age;
}
// UI 构建中的断言(仅开发时)
Widget build(BuildContext context) {
// 确保 context 不为 null
assert(context != null);
// 确保有父级 Scaffold
assert(debugCheckHasMaterial(context));
return Scaffold(...);
}
断点调试
在 VS Code 或 Android Studio 中设置断点进行调试。
VS Code 调试
- 在代码行号左侧点击设置断点
- 按 F5 或点击调试按钮启动调试
- 使用调试工具栏控制程序执行
常用断点命令
| 操作 | 说明 |
|---|---|
| Continue / F5 | 继续执行到下一个断点 |
| Step Over / F10 | 单步执行,不进入函数 |
| Step Into / F11 | 单步执行,进入函数 |
| Step Out / Shift+F11 | 跳出当前函数 |
Flutter Inspector
Flutter Inspector 是 DevTools 的一部分,用于可视化和检查 Widget 树。
主要功能
- Widget Tree: 查看 Widget 层级结构
- Layout Explorer: 检查布局约束
- Performance Overlay: 显示性能指标
常见问题调试
实例:调试 UI 不更新
// 问题:UI 不更新
// 原因:修改状态后没有调用 setState
// 错误示例
void _increment() {
_counter++; // 状态已改变,但 UI 不会更新!
}
// 正确示例
void _increment() {
setState(() {
_counter++; // 必须调用 setState
});
}
// 问题:状态管理混乱
// 建议:使用 Provider 或其他状态管理方案
// 原因:修改状态后没有调用 setState
// 错误示例
void _increment() {
_counter++; // 状态已改变,但 UI 不会更新!
}
// 正确示例
void _increment() {
setState(() {
_counter++; // 必须调用 setState
});
}
// 问题:状态管理混乱
// 建议:使用 Provider 或其他状态管理方案
调试时常用工具:print 输出日志、Inspector 检查 Widget 树、Timeline 分析性能。
点我分享笔记