跳转到正文
YGJoon 技术博客

Flutter 热重载和热重启机制

发布于:
·1.5k 字 · 约 4 分钟·作者:
热重载只重建 Widget 树、保留状态,适合调 UI;热重启清掉状态重跑 main,改静态变量或全局状态时用它
Flutter 热重载和热重启机制文章封面
目录

热重载(Hot Reload)

1. 什么是热重载

热重载是 Flutter 的一个重要特性,它允许在应用运行时动态更新代码,而无需重启应用。这大大提高了开发效率。

2. 工作原理

热重载的实际流程是:

  1. flutter tool 扫描变更的 Dart 文件,增量编译成 kernel
  2. 通过 Dart VM Service 把新的 kernel 注入正在运行的 Dart VM
  3. VM 对所有 State 调用 reassemble(),触发整树 rebuild
  4. main() 和 initState() 不会重新执行,已有状态原样保留

3. 使用场景

热重载适用于:

热重启(Hot Restart)

1. 什么是热重启

热重启会重新运行应用程序,但比完全重启要快,因为它复用了已编译的代码。

2. 工作原理

热重启的实际流程是:

  1. Dart VM 销毁当前 isolate,状态全部清空
  2. 已编译好的 kernel 被复用(这就是它比冷启动快的原因),重新执行 main()
  3. 整个应用从头初始化,所有状态重新生成

注意:热重启只重载 Dart 层。改了原生代码(Kotlin/Swift/C++)、pubspec 依赖或 main() 函数本身,必须完全重新运行,热重启也救不了。

3. 使用场景

热重启适用于:

改原生代码、加依赖、改资源文件,走热重启也没用,必须 stop 后重新 flutter run。

实现机制

热重载不是”重新跑一遍应用”,它的核心是 Dart VM 的代码热替换能力:

  1. 开发期通道:flutter run 启动后,flutter tool 与设备上的 Dart VM 之间通过 VM Service(DevTools 也用同一协议)保持连接,终端里按 r 或 IDE 点闪电按钮,就是往这个通道发 reloadSources 请求。
  2. 增量编译:只有变更的 Dart 库被重新编译成 kernel,注入正在运行的 isolate,未变更的代码原样保留——所以热重载通常 1 秒内完成。
  3. 状态保留:VM 注入新代码后,对所有 State 调用 reassemble() 触发 rebuild,但 State 对象本身不重建,initState() 不再执行,成员变量的值原样保留。
  4. 热重启的区别:热重启走的是”重置 isolate + 复用 kernel 重跑 main()”,状态清零但省掉了重新编译的时间,所以比冷启动快、比热重载慢。

热重载不生效的典型情况

这些情况请直接用热重启(R)或完全重新运行。

最佳实践

  1. 调 UI 用热重载(r),调状态用热重启(R):这是最基本的一分二。凡是涉及初始化逻辑、单例、全局状态的修改,别跟热重载较劲,直接 R。
  2. 把”可热重载”写进代码结构:初始化逻辑尽量收敛到 initState 或单例的 init() 里,而不是散落在 build 中——这样热重载后的 rebuild 行为是可预测的。
  3. 用 const 构造函数:热重载触发整树 rebuild,const widget 会被复用,能明显减少重载后的卡顿。
  4. 记录重载耗时:热重载如果经常超过 3 秒,说明变更的代码被太多文件依赖,考虑拆分大文件——这是代码异味的信号,不是工具的问题。
  5. 状态丢失先查 reassemble:自定义的 State 如果重写了 reassemble() 做了特殊处理,热重载行为可能跟预期不一致,先看这里。

常见问题和解决方案

1. 热重载失败

常见原因:

解决方案:

2. 状态丢失

预防措施:

3. 性能问题

优化建议:

实战案例

做 flutter_brightness(Windows 桌面应用:串口读光照传感器、用 win32 调系统亮度)时,我对热重载的边界体会特别深。改 UI 布局、调 lib/utils/brightness_mapping.dart 里映射算法的参数,按 r 秒级生效;但只要动了 serial_service.dart 里跟 flutter_libserialport、win32、ffi 相关的初始化逻辑——比如改波特率 9600 的配置——热重载经常不生效,必须热重启:原生层的串口句柄和 FFI 绑定已经建好,Dart 侧重载换不掉。教训:调硬件相关代码别跟热重载较劲,直接按 R 热重启,反而更快。

总结

Flutter 的热重载和热重启机制极大地提升了开发效率:

  1. 热重载提供快速的开发反馈
  2. 热重启解决复杂的状态问题
  3. 合理使用可提高开发效率
  4. 了解原理有助于解决问题

掌握这些机制的工作原理和最佳实践,可以帮助我们更高效地进行 Flutter 开发。


分享这篇文章:


相关文章

上一篇
Flutter 生命周期管理详解
下一篇
Flutter 错误处理和日志管理