Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the method of Flutter mixed development

2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

Today, the editor will share with you the relevant knowledge about what the method of Flutter mixed development is. The content is detailed and the logic is clear. I believe most people still know too much about this knowledge, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.

Why do you want to mix the scheme?

App with a certain scale usually has a set of mature and general-purpose basic libraries, especially Ali App, which generally depends on many basic libraries in the system. Then using Flutter to redevelop App from scratch is costly and risky. Therefore, progressive migration in Native App is a robust way for Flutter technology to be applied in existing Native App.

Xianyu precipitated a set of his own hybrid technology scheme in practice. In this process, we communicate closely with the Google Flutter team and listen to some official suggestions. At the same time, we also select the scheme and implement it according to the specific situation of our business.

A mixed plan put forward by the government

1 basic principles

The Flutter technology chain mainly consists of Flutter Engine implemented by C++ and Framework implemented by Dart (the supporting compilation and build tools are not discussed here). Flutter Engine is responsible for thread management, Dart VM state management and Dart code loading. The Framework implemented by Dart code is the main API that the business comes into contact with, and concepts such as Widget are Framework content at the Dart level.

At most one Dart VM can be initialized in a process. However, a process can have multiple Flutter Engine, and multiple Engine instances share the same Dart VM.

Let's look at the implementation. For every FlutterViewController initialized on iOS, an engine is initialized, which means that there will be new threads (which can theoretically be reused) to run Dart code. Android-like Activity will have a similar effect. If you start multiple engine instances, note that the Dart VM is still shared at this time, except that the code loaded by different Engine instances runs on their own Isolate.

2 official suggestion

Engine deep sharing

In terms of hybrid solutions, we discussed some possible options with Google. The official advice from Flutter is that in the long run, we should support the ability to support multi-window rendering in the same engine, at least logically that FlutterViewController shares the resources of the same engine. In other words, we want all drawing windows to share the same main Isolate.

But the official long-term advice is not well supported at the moment.

Multi-engine mode

The main problem we solved in the hybrid solution was how to deal with alternating Flutter and Native pages. The Google engineer came up with a Keep It Simple solution: for consecutive Flutter pages (Widget) only need to be opened in the current FlutterViewController, for the interval Flutter pages we initialize the new engine.

For example, we do the following set of navigation operations:

Flutter Page1-> Flutter Page2-> Native Page1-> Flutter Page3

We just need to create different Flutter instances in Flutter Page1 and Flutter Page3.

The advantage of this scheme is that it is easy to understand and logical, but it also has potential problems. If a Native page and a Flutter page alternate all the time, the number of Flutter Engine will increase linearly, and the Flutter Engine itself is a heavy object.

The problem of multi-engine mode

Redundant resource problems. In multi-engine mode, the Isolate of each engine is independent of each other. Logically this does no harm, but the bottom layer of the engine actually maintains memory-consuming objects such as image caches. Imagine that each engine maintains its own image cache, and the memory pressure will be very high.

There is a problem with plug-in registration. Plug-ins rely on Messenger to deliver messages, while Messenger is currently implemented by FlutterViewController (Activity). If you have multiple FlutterViewController, the registration and communication of plug-ins will become chaotic and difficult to maintain, and the source and destination of message delivery will become uncontrollable.

Page differentiation between Flutter Widget and Native. The Flutter page is Widget,Native and the page is VC. Logically, we want to eliminate the differences between Flutter pages and Naitve pages, otherwise we will encounter additional complexity in page embedding and other unified operations.

Increase the complexity of communication between pages. If all Dart code runs on the same engine instance, they share an Isolate and can communicate between Widget using a unified programming framework, which is further complicated by multiple engine instances.

Therefore, considering many aspects, we did not adopt the multi-engine hybrid scheme.

Present situation and thinking

We mentioned earlier that there are some practical problems with multiple engines, so Xianyu's current hybrid scheme is to share the same engine. This solution is based on the fact that we can only see at most one page at any time, and of course there are specific scenarios where you can see multiple ViewController, but we won't discuss these special scenarios here.

We can simply understand this solution: we treat the shared Flutter View as a canvas and then use a Native container as a logical page. Each time we open a container, we tell Flutter View through the communication mechanism to draw the current logical page, and then put the Flutter View in the current container.

This solution cannot support the situation where there are multiple level logical pages at the same time, because you have to operate from the top of the stack when you switch pages, and you can no longer maintain the state while switching at the same time. For example: there are two pages, Aline B, which is currently at the top of the stack. To switch to A, we need to Pop B from the top of the stack. At this time, the state of B is lost. If we want to switch back to B, we can only reopen the state of the page before B.

For example, in the process of pop, the official Dialog of Flutter may be mistakenly killed. And based on the stack operation, we rely on a property modification to the Flutter framework, which makes this scheme intrusive.

A new generation of hybrid technology solution FlutterBoost

1 reconfiguration plan

In the process of Xianyu promoting fluter, the more complex page scene gradually exposed the limitations and some problems of the old scheme. So we launched a new hybrid technology solution codenamed FlutterBoost (a homage to C++ Boost library). Our main objectives of this new hybrid scheme are:

Reusable and universal hybrid scheme

Support for more complex mixed modes, such as support for home page Tab

Non-intrusive scheme: no longer rely on modified Flutter scheme

Support for general page lifecycle

Unified and clear design concept

Similar to the old scheme, the new scheme is implemented in the mode of shared engine. The main idea is that the Native container Container drives the Flutter page container Container through messages, so as to achieve the synchronization of Native Container and Flutter Container. We want the content of Flutter rendering to be driven by the Naitve container.

To put it simply, we want to make the Flutter container feel like a browser. Fill in a page address, and then the container manages the drawing of the page. On the Native side, we only need to care if the container is initialized, and then set the corresponding page flag for the container.

2 main concepts

3 Native layer concept

Container:Native container, platform Controller,Activity,ViewController

Container Manager: manager of the container

Adaptor:Flutter is the adaptation layer

Messaging: message Communication based on Channel

4 Dart layer concept

The container used by Container:Flutter to hold Widget, which is implemented as a derived class of Navigator-

Management of Container Manager:Flutter containers, providing Api such as show,remove

Coordinator: the coordinator, which accepts Messaging messages, is responsible for the state management of invoking Container Manager.

Messaging: message Communication based on Channel

5 understanding of the page

The objects and concepts that represent the page in Native and Flutter are inconsistent. In Native, our concept of a page is generally ViewController,Activity. For Flutter, our concept of a page is Widget. We want to unify the concept of a page, or weaken the concept of a page that abstracts out the Widget corresponding to Flutter itself. In other words, when a Native page container exists, FlutteBoost guarantees that there must be a Widget as the content of the container. Therefore, when we understand and perform routing operations, we should follow the container of Native, and Flutter Widget depends on the state of the container of Native pages.

So when we talk about pages in the concept of FlutterBoost, we mean the Native container and the Widget to which it is attached. All page routing operations, opening or closing pages, are actually direct operations on the Native page container. No matter where the routing request comes from, it will eventually be forwarded to Native for routing operation. This is why you need to implement the Platform protocol when connecting to FlutterBoost.

On the other hand, we cannot control the business code to push the new Widget through Flutter's own Navigator. For cases where the business uses Navigator directly to operate Widget instead of FlutterBoost, including non-full-screen Widget such as Dialog, we recommend that the business is responsible for managing its status. This type of Widget does not belong to the page concept defined by FlutterBoost.

Understanding the concept of pages here is essential to understanding and using FlutterBoost.

6 the main difference between the old plan and the old one

We mentioned earlier that the old scheme maintains a single Navigator stack structure at the Dart layer for Widget switching. The new scheme is to introduce the concept of Container on the Dart side, no longer using the stack structure to maintain the existing pages, but by flattening key-value mapping to maintain all the current pages, each page has a unique id. This structure naturally supports page search and switching, and is no longer subject to the problem of stack top operation, and some previous problems caused by pop can be easily solved. There is no need to rely on modifying the form of Flutter source code to operate the page stack, which removes the intrusiveness of the implementation.

In fact, the Container we introduced is Navigator, that is, a container of Native corresponds to a Navigator. So how do you do that?

The realization of 7 Multi-Navigator

Flutter provides an interface that allows you to customize Navigator at the bottom, and we have implemented an object that manages multiple Navigator. Currently, there will be at most one visible Flutter Navigator, and the page contained in this Navigator is the page corresponding to our current visible container.

The Native container corresponds to the Flutter container (Navigator) one by one, and the life cycle is synchronized. When a Native container is created, a container for Flutter is also created, and they are associated with the same id. When the Native container is destroyed, the Flutter container is also destroyed. The state of the Flutter container is to follow the Native container, which is what we call the Native driver. Manager uniformly manages to switch the containers currently displayed on the screen.

We use a simple example to describe the process of creating a new page:

Create a Native container (iOS ViewController,Android Activity or Fragment).

The Native container notifies Flutter Coordinator that a new container is created through the message mechanism.

Flutter Container Manager is then told to create the corresponding Flutter container and load the corresponding Widget page in it.

When the Native container is displayed on the screen, the container sends a message to Flutter Coordinator notifying the id of the page to be displayed.

Flutter Container Manager finds the Flutter Container of the corresponding id and sets it as a container visible to the foreground.

This is the main logic for creating a new page, and operations such as destroying and entering the background are also similar to being driven by Native container events.

Summary

At present, FlutterBoost has supported all the Flutter-based development business in Xianyu client in the production environment, providing support for more negative and complex mixed scenarios and providing stable services for 100 million users.

At the beginning of the project, we hoped that FlutterBoost could solve the general problem of Native App mixed mode access to Flutter. So we made it into a reusable Flutter plug-in, hoping to attract more interested friends to participate in the construction of the Flutter community. In the limited space, we share Xianyu's experience and code accumulated in the Flutter hybrid technology solution. Interested students are welcome to actively communicate and study with us.

Expansion and supplement

1 performance dependent

When switching between two Flutter pages, we need to save the screenshot of the previous page because we have only one Flutter View. If there are multiple screenshots of the Flutter page, it will take up a lot of memory. Here we use the two-level caching strategy of file memory, in which only 2-3 screenshots are saved in memory, and the rest of the written files are loaded as needed. In this way, we can maintain a relatively stable level of memory while ensuring the user experience.

In terms of page rendering performance, the AOT advantages of Flutter are fully exposed. When the page changes quickly, Flutter can be very sensitive to the switching of the page, logically creating a sense of Flutter multiple pages.

2 support for Release1.0

At the beginning of the project, we developed based on the Flutter version currently used by Xianyu, and then conducted a Release 1.0 compatibility upgrade test so far no problems were found.

3 access

As long as it is an integrated Flutter project, it is very convenient to introduce FlutterBoost in the form of plug-ins in an official dependent way, and you only need to access the project with a small amount of code. These are all the contents of the article "what is the method of Flutter mixed development?" Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report