Author: Idle fish technology – Jun love

1. Introduction

Since Flutter was introduced by the Idle Fish Technology team in 2018, more and more business scenarios have been used on Flutter. Flutter’s subsecond thermal reloading has always been a great tool for developers, allowing them to quickly modify the UI, add features, and fix bugs without having to restart the application to see the changes made.

So how does hot loading work?

This article takes you step by step to uncover the mystery of Hot Reload.

2. Source code analysis

2.1 FlutterTools debugging

To understand how HotReload works, first we need to master the debugging methods of Flutter_tools.

As an example, we create a simple FLUTTER project called Fluttertest.

Use open AndroidStudio flutter_tools (/ flutter/packages/flutter_tools), breakpoint is set for the HotRunner. Restart () method

Add a new Debug Configurations with the Woking directory set to the Fluttertest project address

Trigger the Flutter_Tools DEBUG button. After the APP starts, simply change the Fluttertest code

Enter r on the Flutter_tools Debug Console to start debugging.

Breakpoint successful!

HotReload Basic flow

So how does HotReload work?

When we run HotReload, either by typing r on the console or by clicking lightning, we end up running the hotrunner.restart (fullRestart: false) method in flutter_tools (breakpoint above).

The restart() method calls _reloadSources(pause: pauseAfterRestart), which is the main part of the HotReload code.

(source is located in the/flutter/packages/flutter_tools/lib/SRC/run_hot dart)

Future<OperationResult> _reloadSources({ bool pause = false })
Copy the code

In _reloadSources:

  1. First _updateDevFS will () in the project file by scan, check whether there is a delete, add or change, after the scan is complete, to generate the kernel files, named app. Dill. Incremental. Dill file, sent via HTTP port to DartVM;
  2. The generated. Dill file path is scanned, and the resource is loaded by calling _reloadSources through RPC interface.
  3. Confirm that the VM resources have been reloaded successfully, reset the FlutterDevice UI thread, and trigger the flutter Widgets tree to rebuild and redraw via the RPC interface

To understand this process, it is necessary to understand the compilation mode of Flutter.

Compilation modes can be roughly divided into two types, AOT compilation and JIT compilation. The full name of JIT is Just In Time. Code can be compiled at the Time of program execution because it needs to be analyzed and compiled before the program is executed. JIT compilation may lead to slow program execution. AOT compilation, full name Ahead Of Time, is compiled before the program runs. It changes the code from the developer and compiles slowly. However, it does not need to be analyzed and compiled during runtime, so the execution speed is faster.

Flutter uses a unique compilation mode. In the development phase, dart code is generated into toggled source code using Kernel Snapshot mode (corresponding to JIT compilation), which is compiled at runtime and interpreted for execution. In the release stage, ios uses AOT compilation, and the compiler generates the DART code into assembly code and finally generates app.framwork. Android uses Core JIT compilation, and Dart is converted into binary mode and loaded before VM startup.

Therefore, based on the Kernel Snapshot compilation mode at the development stage, we can know that Hot Reload scans the project file, transforms the changed DART file into Kernel files with token source code, and sends them to the running DartVM. DartVM replacement resources. Then tell the Flutter Framework to rebuild, rearrange, and redraw WidgetsTree to see the changes.

Here, we already know HotReload basic operation process, but the app. Dill. Incremental. What’s the dill file, and how and replacing the old files?

2.2 Incremental code scanning

App. Dill file is automatically generated in project directory/Fluttertest /build after application startup, before HotReload startup, and after successful compilation.Through the strings command parsing, it is found to be the tokenized source code, which contains the complete business code.

(It is longer and only part of it is taken)

At the same time, through the adb shell check, found in the device/data/data/com loommo. Fluttertest/com. Loommo. Fluttertest app_flutter/flutter_assets, generate three files;

Kernel_blob. bin parses the strings command to find the same content as app.dill.

After the application is started for the first time, the complete service code file app.dill is displayed on the device as kernel_blob.bin.

So we’re gonna start HotReload, _updateDevFS() and when we’re done with that step,

(the source code in the/flutter/packages/flutter_tools/lib/SRC/would dart)

Future<int> update({@required String mainPath,String target,AssetBundle bundle,DateTime firstBuildTime,bool bundleFirstUpload = false,bool bundleDirty = false,Set<String> fileFilter,@required ResidentCompiler generator,String dillOutputPath,bool fullRestart = false,String projectRootPath,@required String pathToReload,})
Copy the code

Check the project, project directory can be found under/fluttertest/build/new app. Dill. Incremental. Dill files, through the strings command parsing, found the dart files contain only what we changed.

At the same time, through the adb shell inspection, found that the equipment in/data/data/com loommo. Fluttertest/cache/fluttertestYAYDGJ/fluttertest/lib, Also added a main. Dart. Incremental. Dill, through the strings command parsing.

Sure enough, and the app. Dill. Incremental. Dill content consistent.

The/data/data/com. Loommo. Fluttertest/com. Loommo. Fluttertest/app_flutter/flutter_assets/kernel_blob. Bin has not changed.

On the Flutter can know the Tools generated app. Dill, incremental, dill, through RPC calls _reloadSources, actual trigger, Flutter in the Engine DartVM Reload method, the method, Incremental compilation for.increment. dill to replace compiled products and update modified files.

(source is located in the/engine/SRC/third_party/dart/runtime/vm/isolate_reload cc)

void IsolateReloadContext::Reload(bool force_reload,const char* root_script_url,const char* packages_url_)    
Copy the code

Subsequent articles continue in-depth analysis, interested students can read the source code carefully first.

2.3 WidgetsTree reconstruction

As we know from the above, Hot Reload notifies the Flutter framework after reloading the resource, triggering the re-establishment, relayout, and redrawing of the Widgets tree.

So how does a flutter trigger the rebuild of the Widgets tree?

Dart VM Service Reassemble is registered by BindingBase in the Flutter framework to externally communicate with the running Dart VM, triggering root tree reconstruction operations.

When the service is triggered, BindingBase.reassembleApplication-> WidgetsBinding. performReassemble -> BuildOwner.reassemble -> Element.reassemble Step by step, rebuild the Widgets tree from the root node.

(source is located in the/flutter/packages/flutter/lib/SRC/foundation/binding. The dart)

Future<Null> reassembleApplication()
Copy the code

3. The conclusion

Flutter is different from previous Native development and has been widely praised for its subsecond thermal overload. Understanding the principle of HotReload can help us in our daily development and provide theoretical support for subsequent dynamic solutions.

4. Reference documents

  1. Dart VM service protocol
  2. In-depth understanding of flutter compilation and optimization
  3. Using Hot Reload
  4. The source code used above

Join the idle fish for some “cool” fun

Idle fish technology team is a dapper engineering technology team. We not only pay attention to the effective solution of business problems, but also promote the cutting edge practice of computer vision technology in mobile terminals by breaking the division of division of technology stack (the unification of android/iOS/Html5/Server programming model and language). As a software engineer in the Idle Fish technology team, you have the opportunity to demonstrate all your talents and courage in the evolution of the entire product and user problem solving to prove that technology development is a life-changing force. Resume: [email protected]