04 | Flutter is the key technology of different from other solutions?
How does Flutter work?
Flutter is a complete solution that rewrites both the underlying rendering logic and the upper development language.
The essential differences between Flutter and other cross-platform solutions:
Frameworks such as React Native simply invoke system components through JavaScript VIRTUAL machine extensions, and render components by Android and iOS systems.
Flutter completes its own loop of component rendering.
How does Flutter render its components?
In computer system, CPU is responsible for image data calculation, GPU is responsible for image data rendering, and the display is responsible for the final image display. The CPU gives the calculated content to be displayed to the GPU, and the GPU completes the rendering and puts it into the frame buffer. Then the video controller reads the frame data from the frame buffer and submits it to the display to complete the image display at the speed of 60 times per second according to the VSync signal.
What is Skia?
Skia is a powerful 2D image rendering engine developed in C++. Based on Skia, Flutter has complete cross-platform rendering capabilities.
The principle of Flutter
- Embedder is an operating system Embedder layer that provides the ability to embed platform-specific features such as render Surface Settings, thread Settings, and platform plug-ins.
- The Engine layer contains Skia, Dart and Text, which implements the rendering Engine, Text typesetting, event processing and Dart runtime of Flutter. Skia and Text provide the ability to call the underlying rendering and typesetting for the upper interface, while Dart provides the ability to call Dart and the rendering engine at runtime for Flutter. The Engine layer combines them to render views from the data they generate.
- The Framework layer is a UI SDK that uses Dart and includes animation, graphics, and gesture recognition. To provide a more intuitive and convenient interface for drawing fixed graphics such as controls, Flutter also builds on these basic capabilities by encapsulating a library of UI components based on the Material and Cupertino visual design styles. We can use these libraries directly when developing Flutter.
Take the interface rendering process as an example and tell you how Flutter works.
Widgets on a page are organized in a tree, a control tree. Flutter makes up the tree of rendered objects by creating different types of render objects from each control in the control tree. The rendering of object trees in Flutter is divided into four stages: layout, drawing, composition and rendering.
Layout (similar to Android onMeasure and onLayout, first determine the size and location of the child View)
Flutter uses a depth-first mechanism to traverse the tree of rendered objects and determine their position and size on the screen. In the layout process, each render object in the render object tree will receive the layout constraint parameters of the parent object, determine its own size, and then the parent object according to the control logic to determine the location of each child object, complete the layout process.
Draw (similar to Android’s onDraw method)
Once the layout is complete, each node in the rendered object tree has a definite size and location. Flutter draws all rendered objects onto different layers. Like the layout process, the drawing process is depth-first traversal and always draws itself first before its children.
Here’s an example: After node 1 draws itself, node 2 is drawn, then its children nodes 3, 4, and 5 are drawn, and finally node 6 is drawn.
To solve this problem, Flutter proposes a mechanism corresponding to the layout Boundary — the Repaint Boundary. Within the redrawn boundary, Flutter forces new layers to change. This avoids the interaction between inside and outside the boundary and prevents unnecessary redrawing of irrelevant content on the same layer.
Composition and rendering
Terminal equipment page more and more complex, so the render tree levels are usually a lot of Flutter, directly delivered to the rendering engine to render multiple layers, there may be a large number of rendering content repetition of rendering, so you also need to make a first layer synthesis, is all layers according to size, levels, such as transparency rules to calculate the final show effect, Group and merge the same layers to simplify the rendering tree and improve rendering efficiency.
After the merger, Flutter will submit the geometric layer data to the Skia engine for processing into 2d image data, which will finally be rendered by GPU to complete the display of the interface.
05 | Flutter engineering
First, we open Android Studio and create a Flutter engineering application, Flutter_app. Flutter automatically generates a simple counter application, Demo, based on its own application template.
Engineering structure
Flutter injects related dependencies and build artifacts into the two subprojects, eventually integrating them into their respective projects. The Flutter code we developed will eventually run as a native project.
Below is the Demo code flow chart
Note that state changes must be made in conjunction with setState.
Widgets are simply “configuration information” for views, maps of data, and are “read only.” In the case of statefulWidgets, we need to recreate the Widget to update the interface when the data changes, which means that the Widget is created and destroyed frequently.
To this end, Flutter optimizes this mechanism by using an intermediate layer within its framework to minimize changes to the real render view and improve rendering efficiency, rather than destroying the entire render tree if the upper UI configuration changes.