Flutter’s hot Reload feature helps you quickly and easily test, build the user interface, add features, and fix bugs without having to restart your application. Hot reload is achieved by injecting the updated source file into the running Dart Virtual Machine (VM). After virtual machines update classes with new fields and functions, the Flutter framework automatically rebuilds the widget tree to quickly see the effect of the changes.
The working principle of
Differences between JIT and AOT:
JIT (Just In Time) : Refers to just-in-time compilation or runtime compilation. Used In Debug mode, it can dynamically deliver and execute code. The startup speed is fast, but the execution performance is affected by runtime compilation.
AOT (Ahead Of Time) : Ahead Of compilation or run-time compilation. Used in Release mode, AOT can generate stable binary code for a specific platform with good execution performance and high running speed. However, AOT needs to be compiled in advance for each execution, resulting in low development and debugging efficiency.
As you can see, in both compilation modes, AOT is compiled statically and the final product is compiled into machine code that can be directly executed, while JIT is compiled dynamically and dart code is compiled into intermediate code that is interpreted by the DART VM as the program runs.
Steps for thermal overloading:
- Engineering changes: Thermal overload
Server
Each file in the project is scanned for additions, deletions, or changes until it finds Dart code that has changed since the last compilation. - Incremental compilation: The hot-reload module converts the changed Dart code into incremental compilation
Dart Kernel
File. - Push updates: Hot-reload the Server to pass the incremental Dart Kernel file
RPC
Protocol, sent to the one that’s running on the phoneDart VM
. - Code merge: The Dart VM merges the received incremental Dart Kernel file with the existing Dart Kernel file and then reloads the new Dart Kernel file.
- Widget incremental rendering: Flutter resets its UI thread, notifies, after confirming that the Dart VM resource has been successfully loaded
flutter.framework
Reconstruction of the Widget.
Scenarios where hot overloading is not supported
- Changes in the main method
- Changes in the initState method
- A compilation error occurred in the code
- Changes to global variables and static properties
- The status of the Widget is incompatible
- Enumeration and generic type changes
Hot overload source code analysis
Start process Parsing
First create a flutter project, hotload_demo, find flutter-> Packages -> Flutter_tools, open it through Android Studio, and then open Edit Configurations. Create project hotload_demo and configure Working directory (Program arguments).
- Start debugging and run the project in
bin->flutter_tools.dart
The breakpoint is set on the main function in the
- Enter the
main
Function, found parsing the parameters passed in, and then doing some callback processing
- Now we see that it’s called
runner.run(args)
methods
- After the run method is called, it is called
run.dart
The inside of therunCommand()
methods
- In the runCommand() method you’ll find our device, which you can see is the emulator device I’m running on
iPhone 12 pro Max
- Continued debugging found that the terminal printed
Running Xcode build... , xcode build done
These are in themac.dart
Internally processed
Call up some instructions for Xcode to compile and execute
- We can see this in the runCommand () method
The terminal is registered and started
the
setupTerminal()
The help information is printed in the method. WhatR, r,
And so on, and now you see that you’re also listening for terminal input
- If you look at the implementation of printHelp, it prints out the help information
- It turns out that there are two urls at the bottom of the terminal, and the top one is
The dart vm
The bottom one isDevtools
Debugging tool, Devtools can be used for performance debugging
Scanning incremental files
- Listen for terminal input and process it
Here you can see that the input r corresponds to the processing, hot update of the main execution of the code
- The input
r
forhot reload
Refresh the displayresidentRunner.restart(fullRestart: false)
Continue with the following method in restart
- To follow uprestartMethod inside
_fullRestartHelper
Methods and_reloadSources
Method to reload the resource file
- Log the load time of hotreLoad, and then update the increment file
- To follow up
_updateDevFS
Update the increment file, find the device to perform the update file, and then follow in to find the update method
- To obtain
content
And then look for the file, and then the terminal goes to the directory, and typestrings app.dill.incremental.dill
If there are changes, you can output the contents of the changed file
- This is the file that we found from the path,
app.dill.incremental.dill
Contains the contents of the incremental file
Transfer add files to the Dart VM
- Transferring incremental files
DevFSContent
To the virtual machine, yes_httpWriter.writer
Asynchronous goRPC
The protocol is written to DartVM for updateawait _httpWriter.write(dirtyEntries);
.
So if you look at the _httpWriter there is a property called httpAddress which is the address of the Dart VM
- So when is the virtual machine created
run
Create, and there will be a series of registrations
Hot overload engine tuning
Since I downloaded the Code of the Flutter engine and compiled it into the corresponding iOS project, this can be combined here.
- How do I get the iOS project in the Flutter project to use the locally compiled engine that is required in the Flutter project
Runner
的Generated.xcconfig
Engine in it
// Path of the compile engine FLUTTER_ENGINE=/Users/zhou/engine_download/ SRC // Corresponding simulator debug version LOCAL_ENGINE= iOS_DEBUg_sim_unoptCopy the code
After the configuration was complete and I started running Project Runner, I added a print to the Click method inside the Flutter engine
When I run another project, I click on the screen console and it says yes, that means it’s mounted successfully
- Next joint modulation
flutter tools
That need to be inEdit Configurations
insideProgram arguments
Configuration parameters
run --local-engine-src-path /Users/zhou/engine_download/src --local-engine=ios_debug_sim_unopt
Copy the code
/Users/zhou/engine_download/ SRC /out/ iOS_debug_sim_unopt Find this method, this is the method we call to update the load increment file
Add a breakpoint in the Xcode project you just ran
br set -n "IsolateGroupReloadContext::Reload"
So you have a closed loop, the engine code, the Flutter code, the Flutter tools, and then you have to change the Flutter code, execute r inside the Flutter Tools, Found that this method is implemented to increase the Xcode breakpoint to IsolateGroupReloadContext rendering, verify the steps of thermal overload before.
conclusion
This step by step debugging down to understand the principle of thermal overload. The hot reload of Flutter is code incremental synchronization based on JIT compilation mode. Because the JIT is dynamically compiled and has the ability to compile the Dart code into generated intermediate code that the Dart VM interprets at run time, incremental synchronization can be achieved by dynamically updating the intermediate code.
On the other hand, hot overloading is not supported because it involves saving and restoring state, involving state compatibility and state initialization scenarios, such as incompatible Widget state before and after changes, changes in global variables and static properties, changes in main methods, changes in initState methods, changes in enumerations and generics, etc.
As you can see, hot overloading improves the efficiency of debugging the UI and is ideal for writing interface styles that require repeated review of changes. However, hot overloading itself has some unsupported boundaries due to its state preservation mechanism.
Reference article:
www.jianshu.com/p/46b43554b…
zhuanlan.zhihu.com/p/89870807