Flutter hot update technology refers to the ability to update application code and resources without recompiling and redeploying the application. This allows developers to quickly fix bugs, add new features, and improve application performance without requiring users to redownload and reinstall the application.In the era of AI, using AI to generate high-quality code is a standout feature. Take AI Design for example, a tool that effortlessly converts screenshots into editable Figma UI designs. Simply upload an image of any app or website, and it smoothly handles the conversion process. Additionally, AI Code enhances this functionality by facilitating Figma-to-Code translations, supporting a wide range of platforms including Flutter for Unified Cross-Platform Development on Android, iOS, and macOS, and ensures the creation of highly accurate code.
2. Analysis of Flutter Hot Update Technology Directions
After analysis, there are currently three feasible hot update solutions:
A solution similar to the React Native (RN) framework
Dynamic component framework for pages
Custom Dart Virtual Machine solution
The following table compares these three solutions:
Solution Name
Principle
Advantages
Disadvantages
RN-like solution
Written in JavaScript, converted to Flutter atomic widgets
iOS natively supports JS, enabling updates
Performance impact, high learning cost, Android requires JS library
Dynamic component framework for pages
Compile-time instrumentation, dynamic JSON delivery, data matching to replace Widget
Supports Android/iOS updates
UI updates easy, business logic difficult, high maintenance cost
Custom Dart VM solution
Modify Flutter Engine to implement hot updates
Small performance impact, high dynamism
Need to maintain different versions of the Flutter engine
This article will focus on the third solution - the Custom Dart Virtual Machine solution.
3. Preliminary Knowledge
Before delving into hot update technology, we need to understand some basic concepts:
3.1. Flutter Compilation Modes
Flutter's compilation modes come from Dart's compilation modes, mainly divided into JIT (Just In Time) and AOT (Ahead Of Time).
Compilation Mode Name
Features
Advantages
Disadvantages
JIT
Just-in-time compilation, like the V8 engine
Dynamic code execution, provides dynamic content
Large compiler overhead, poorer performance
AOT
Pre-compilation, like GCC
Fast load and execution speed
Different CPU architectures, larger binary packages, iOS cannot dynamically update
Flutter has three compilation modes: Debug, Release, and Profile:
Debug mode corresponds to JIT, supports devices and simulators, and supports rapid development and HotReload.
Release mode corresponds to AOT, supports real devices, and optimizes package size and execution speed.
Profile mode is similar to Release but retains debugging features to aid in performance analysis.
3.2. Analysis of Flutter Compilation Artifacts
On iOS and Android platforms, a Flutter project is essentially a standard native project. On the iOS platform, App.framework and Flutter.framework are generated through shell scripts in BuildPhase; on the Android platform, flutter.jar and compiled binary files are added through Gradle.
Analysis of the engine layer structure and compilation artifacts shows that, whether on iOS or Android, the APP business code consists of four segments: kDartVmSnapshotData, kDartVmSnapshotInstructions, kDartIsolateSnapshotData, and kDartIsolateSnapshotInstructions. In theory, as long as the loaded code and data segments can be dynamically replaced, hot updates can be achieved.
Currently, there are mainly two Flutter hot update solutions:
Hot Restart: Hot Restart refers to reloading application code and resources without recompiling the application. This is a quick and simple hot update method, but it can only update the application's code and resources, not the binary files.
Hot Reload: Hot Reload refers to reloading the application's binary files without recompiling the application. This is a more complex but more powerful hot update method that can update the application's code, resources, and binary files.
Implementation Principle:
The implementation principle of Flutter hot update technology is based on the incremental compilation feature of the Dart Virtual Machine (DVM). The DVM can compile Dart code into bytecode and store it in the application's binary files. When the application needs to be updated, the DVM can incrementally compile new Dart code and merge it with the application's binary files. Thus, the application can update its code and resources without recompilation.
4. Analysis of Hot Update Technology Solutions
4.1. Flutter Code Analysis
Based on the above analysis, we know that the Flutter code consists of four segments, among which kDartIsolateSnapshotData and kDartVmSnapshotData are allowed to be dynamically delivered, while kDartIsolateSnapshotInstructions and kDartVmSnapshotInstructions are not allowed to be dynamically delivered on iOS.
Name
Comment
Function
Note
kDartIsolateSnapshotData
Dart isolate data segment
Class information, global variables, function pointers, etc.
Allowed to be dynamically delivered
kDartIsolateSnapshotInstructions
Dart isolate instruction segment
Contains AOT code executed by Dart isolate
Not allowed to be dynamically delivered on iOS
kDartVmSnapshotData
VM isolate data segment
Initial state of the Dart heap shared between isolates
Allowed to be dynamically delivered
kDartVmSnapshotInstructions
VM isolate instruction segment
Contains AOT instructions for common programs shared among all Dart isolates in the VM
Not allowed to be dynamically delivered on iOS
Note: The meanings of isolate, snapshot, and vm isolate are explained as follows:
Name
Meaning
isolate
Dart is single-threaded, and an isolate is similar to a thread in Dart. The difference between isolates and threads is that threads share memory, while isolates do not share memory. There are no lock contention issues, each Isolate executes independently, has its own event loop, and can only communicate through messages, with lower resource overhead than threads.
snapshot
The serialization of class information, global variables, and function instructions directly onto the disk is called a Snapshot.
vm isolate
A process can have many isolates, but the heap areas of two isolates cannot be shared. The official design of the VM isolate (kDartVmSnapshot) is used to implement interactions between multiple isolates.
4.2. Runtime Analysis of Business Code Loading
The process of loading runtime code in Flutter is as follows:
On the Android side: The Flutter Engine loads libapp.so and flutter_assets.
On the iOS side: The Flutter Engine loads App.framework and Flutter.framework.
4.3. Compilation Generation of Business Code (Compile Time)
At compile time, we need to generate our own code segment and data segment files. The iOS build process compiles Dart code into assembly files through the compiler, and then generates App.Framework through the toolchain. The basic process is "Dart Code (business code)" -> (through Dart compiler gen_snapshot.cc) generates the assembly file snapshot_assemble.S -> (through xcrun tool) generates the obj file snapshot_assemble.o -> (through xcrun clang toolchain) generates App.Framework.
The Android build process is similar, but there are simpler solutions, as shown in the following diagram:
4.4. Exploration of Hot Update Implementation Solutions
The core steps of hot update on the Android side are as follows:
Modify Flutter Engine code: Customize the Flutter Engine to load libapp.so and flutter_assets from a specified path.
Replace Flutter engine during APK compilation: Use the Gradle Transform plugin to dynamically replace the official Flutter engine during APK compilation.
// Example: Use Transform plugin in Gradle script to replace Flutter engine
android {
...
transformations {
replaceFlutterEngine {
// Replacement logic
}
}
}
Generate patch package: Use the BSdiff algorithm to compare the old and new APK files and generate a patch package.
bsdiff old.apk new.apk patch.bspatch
4. **Fetch patch package on APP startup**: At application startup, access the backend interface and fetch the patch package based on parameters.
```dart
// Example: Fetch patch package in Dart code
Future<void> fetchPatch() async {
final patch = await http.get('https://example.com/patch');
if (patch.statusCode == 200) {
// Save the patch package
}
}
Verify and synthesize the patch package: Verify the md5, version number, and other information of the patch package and synthesize a new APK.
Flutter hot update technology is a powerful tool that can help developers quickly fix errors, add new features, and improve application performance without requiring users to redownload and reinstall the application. This makes Flutter a very suitable framework for rapid iteration and updates of applications.
About The Author
Alex Chen
Senior Frontend Developer at Codia AI, specializing in design-to-code automation