# Sharing author



Nickname:Auspicious hada

preface

First of all, I wish everyone a happy Mid-Autumn Festival, and tomorrow I have to work again ~ ha ha ha. However, standing here, National Day may be ~

Anyway, I’d like to share some of my practices with Flutter android for cross-process rendering.

The cause of

As the project iterations, functionality becomes more complex and memory footprint increases. In the process of pressure testing, app crash is mostly due to memory leakage or abnormal jitter for various reasons and OOM is finally triggered and killed by the system. According to technology stack, it is mainly divided into the following two ends:

  1. The code quality of the native end itself (improper design, image loading, unreleased objects, etc.) is caused by this, which can be quickly fixed by backtracking and finding the corresponding students in the group.

  2. The front-end code quality (as above) caused by this need to find the front-end group of students to repair, but across the group/department of the powerless I think everyone more or less will have some.

Regardless of the reason, the App crashed. On the one hand, we found the student responsible for the repair and on the other hand, we were thinking about how to solve the App crash caused by H5 from the original (at least isolated).

Analysis of the

Having some native development experience, we thought of child processes. And through the sub-process to share the memory pressure of the main process, has been applied in major factories, can prove that it is a more mature scheme, and on the single process Web-view, there are many successful Android framework and technical solutions to share on the market.

In terms of pure native (Android) applications, because of the unity of the stack, access to a sub-process Web-view, or more convenient, roughly open a sub-process, and then startActivity, do not need to care about stack management. But Flutter applications fall into two stacks:

1 Android stack (managing activity) 2 Flutter stack (managing route of Flutter)Copy the code

In practical application, H5 and native have complex interaction, which is not only reflected in the function, but also in the UI. Regardless of jump animations, superpositions within a Flutter stack (Flutter and H5) require a separate stack manager (i.e., Flutter Boost).

Considering the input-output cost and the nature of the problem that the stack manager can’t solve (e.g., the part of the Flutter page is H5), I decided to use the Texture Widget that comes with the Flutter to display H5. This helps unify the stack management. Also, the Texture Widget can be freely sized to embed (part of) any Flutter page. The Texture Widget requires a Surface, and the natural cross-process nature of the Surface makes development a lot easier.

Practice and Results

After a period of research and design, we finally have an Alpha version of the framework. Here I would like to make a brief introduction to the architecture:

Division by process

It is mainly divided into two parts:

1. The main process includes Flutter and the corresponding platform, which is responsible for the creation, display and interaction of the surface. 2. Subprocesses mainly include Zygote Activity, WebView, etc.Copy the code

Processes communicate with each other through the Binder.

Division by flow

It is mainly divided into three parts:

1. On the side of Flutter, it mainly initiates the creation instructions and ultimately consumes the rendering data of the child process. 2. On the platform side, it mainly undertakes the communication and forwarding function of Flutter and the web-view of the subprocess, as well as the creation function of the surface. It is also the module that really communicates with the subprocess. 3. Sub-process, mainly responsible for the creation of WebView, and use the surface provided by the main process to output H5 content.Copy the code

Some of the difficulties encountered

The permissions of the system pop-up window are incorrect

Using web-view in a child process and rendering on a given surface requires the use of virtual display and presentation, but if the presentation is not created in an activity-based context, Then a system permission is required to work properly, which is unacceptable for our requirements.

To do this, we created a Zygote Activity that works in the background and is responsible for providing a context and part of the presentation creation. It also uses memory leaks to keep it alive for as long as possible.

interaction

Since system events (such as touches) are distributed to the top of the current (foreground) activity stack, when Zygote activity is working in the background, our touch events are distributed to the Main activity, and H5 cannot respond to any interactions. Therefore, we need to sort the events in the main process and forward them to the child process with binder to make H5 consume its own events.

Distribution and dislocation of touch events

Since the events received by the Flutter are provided by the Main Activity, event distribution is handled here as well. To this end, I added a stack moderator (which is simpler than stack management). To get the stack status of the current Flutter end and make the correct distribution.

After practical practice, the effect is still good, but also found a problem: click coordinate dislocation. It was found that this was mainly caused by the mismatch between the Flutter side layout and the Web View side layout. In other words, it was necessary to calculate the position relative to the Texture widget when the Flutter was clicked and then distribute it.

communication

Objectively speaking, there is no difficulty here, but it is more complicated, because the operation involves UI, so not only the communication between processes, thread switching and the main and child thread switching of each process must be considered. In addition, communication is divided into public and private communication by domain, so a Communicate hub is added to distinguish communication between different domains.

The results of

After some major problems are solved, we get the final debug mode:

The Demo was not production ready, but it proved that it worked, and there was still some work to be done to actually go live, such as coordinate converter optimization (to be done in the next version), coordinator, garbage collection, bottom-pocket strategy, etc.

Here is the end of my sharing, I hope to help you, but also hope that there are leaders can point out the shortcomings of the design, thank you for reading.