Flutter对于开发者来说一个很大的亮点就是它的热重载功能。热重载能帮助我们在无需重启整个应用的情况下快速调整UI,新增功能,修复bug等,能很大程度的节省开发时间,提升效率。Flutter是怎么做到这样快速更新的呢?要理解热重载的实现机制,我们先来了解下Flutter的编译模式。 Flutter编译模式
编译模式主要分为两大类:JIT和AOT。
JIT:Just in time,即时编译,程序执行过程中边翻译边运行,启动速度快,但执行效率相对于AOT会低一些。
AOT:Ahead of time,提前编译,程序在执行前全部被翻译成机器码,减少了运行时的性能损耗,运行更流畅。
Flutter结合了这两种编译方式,开发阶段采用JIT,Release阶段采用AOT。开发阶段边翻译边运行的方式正是热重载功能的前提,运行过程中将有变更的代码文件注入到Dart虚拟机中,虚拟机加载新的文件后,触发重建widget树,从而使开发者能快速看到更新后的效果。
接下来我们结合flutter tools源码深入了解下热重载机制:
Flutter tools
Flutter tools 本质上是一个Dart程序,位于path/to/flutter/packages/flutter_tools路径下,它的入口函数是flutter_tools.dart的main方法:
import 'package:flutter_tools/executable.dart' as executable; void main(List args) { executable.main(args); }
executable.main(args)中组装了很多种类型的FlutterCommand:
await runner.run(args, [ AnalyzeCommand(verboseHelp: verboseHelp), AssembleCommand(), AttachCommand(verboseHelp: verboseHelp), BuildCommand(verboseHelp: verboseHelp), ...... RunCommand(verboseHelp: verboseHelp), ...... UpgradeCommand(), VersionCommand(), ], ...... }
然后在CommandRunner的
Future runCommand(ArgResults topLevelResults)
方法中根据条件遍历执行这些FlutterCommand的runCommand方法,直到有FlutterCommand处理此次命令。重点了解一下RunCommand,RunCommand处理flutter run命令,在它的runCommond方法中会根据hotMode来判断创建HotRunner或ColdRunner(如果不强制指定--no-hot,在debug模式下默认是启用hotMode的),然后执行所创建的HotRunner/ColdRunner的run方法。