The author:TaoTao, prohibit reprinting without authorization.

background

Since its birth, Flutter has become the leader of cross-end development. More and more companies at home and abroad have embarked on the path of Flutter exploration. Our front end team of ZCLOUD University has been trying to develop a small number of pages using Flutter since 2018. In 2019, the front-end group launched the full flutter of Zhiyun Health App (based on the Flutter SDK 1.9.0). After 3 months ‘efforts of the flutter group partners, the Flutter version of Zhiyun Health app was launched steadily.

This article documents the problems we encountered with the full flutter app and explains how we solved them.

Problems with Flutter WebView usage

Introduction to the

Because Flutter transforms the Widget Tree into a texture and then draws its widgets via Skia, the principle of flutter UI is that it cannot use the native Android/IOS controls directly, and therefore cannot use the native mature WebView, MapView, etc. For this situation, we have two solutions:

  • Develop a Plugin, open an Activity/Controller in the Plugin, load and display the native WebView through the Activity/Controller, this scheme can fully reuse all the capabilities of the native WebView, Webviews can also be highly customised on demand, but there is a serious drawback. It is not possible to open the flutter page from an open native WebView. The re-opening of the flutter page is covered by the native WebView. (Such as flutter_webview_plugin is used for this scheme)

  • Before flutter SDK 1.20, there is a PlatformView which is called AndroidView on Android and UIKitView on IOS. Developers can embed Android/IOS Native components into the Widget Tree of Flutter. (The official Webview_flutter implementation uses this approach)

Select the Flutter WebView solution based on the service scenario

  • The first solution only works if a new page is clicked to open the WebView and the Webview does not need to open the flutter page. The advantage of this solution is that the flutter can avoid all the pitfalls that a native control would encounter.

  • The second option is the official practice of using native controls for Flutter via PlatformView. Prior to Flutter SDK1.22, flutter was in a preview state and was not recommended for production, leaving many problems.

    Back to our specific business scenario, there are four tabs on the main interface of Zhiyun Health App, among which community and mall are H5 pages, which need to be loaded by WebView. One process is as follows: shopping mall home page -> commodity purchase page -> customer service chat page, and the customer service chat page is the page developed by Flutter. The first solution obviously did not meet our requirements, so we adopted the official WebView_FLUTTER solution.

    The selection of the official preview version of Webview_flutter has a number of problems that need to be solved, so we have started the long road to flutter webview governance…

The principle of webview_flutter

  • AndroidView:

    How: Prior to flutter SDK 1.20, Flutter draws the content to be rendered into the memory of VirtualDisplay via AndroidView, and then renders it into the Surface via the corresponding textureId. VirtualDisplay is like a VirtualDisplay area. With VirtualDisplay output textures, Android can add native controls directly to the Flutter Widget Tree hierarchy.

    Defect:

    1. Because the AndroidView is rendered in the VirtualDisplay memory, when the user clicks on the AndroidView, it actually clicks on the rendered Flutter Texture. The user’s touch event is sent to the Flutter View. Instead of AndroidView, so this way to achieve AndroidView is the need for special handling of touch events, and the problem caused by special handling is that the touch information is sent incorrectly or lost.

    2. Since the position of VirtualDisplay is always no focus, and the focused Windows of a Flutter are usually actually held and visible to the user, this approach requires special handling of focus issues.

    3. Android WebView has its own internal logic to create and set input connections, which makes the first two problems more complicated. There are all kinds of strange problems, soft keyboard pop-up exceptions, text copy, shared dialog box is not available, and so on

  • UIKitView (IOS) :

    On IOS, the implementation of flutter is different from that on Android, which uses a layer blending method: Flutter has two transparent textures: One is under the IOS native view and one is above the IOS native view. The Flutter UI that is displayed below the IOS native view should be drawn on the transparent texture below, while the Flutter UI that is displayed above the IOS native view should be drawn on the transparent texture above. Finally, combine all the layers to create the desired interface. In this way, IOS can also add native controls directly to the Flutter Widget Tree hierarchy.

    Advantages: All texture combinations are used, still within the rendering logic of the Flutter Widget. There are no special processing problems like those on the Android side.

    So why not on Android?

    The reason is that on iOS there is a callback notification after the frame renders. For example, when the iOS view moves down 1px, we can also render all other Flutter controls in its list down 1px.

    However, there is no system API for rendering callbacks on Android system, which can not achieve synchronous output rendering.

  • Hybird Composition (Android)

    Method: The new Hybird Composition mode of Flutter SDK 1.20 is similar to IOS PlatformView. In this mode, FlutterImageView is added. The FlutterImageView itself is a plain native View with the ability to blend layers. PlatformView mixes layers by adding native controls to the FlutterView and then using the FlutterImageView.

    Improvements: Similar to IOS layer combination implementation, without VirtualDisplay that requires special processing cases, can solve the previous touch, soft keyboard, text functions.

Problems encountered using the official webview_FLUTTER

IOS WebView gets stuck when scrolling

Symptom: Before webView_Flutter0.0.7, the WebView was used to load the H5 page with webview_flutter0.0.7 on IOS. The page was stuck when the flutter was slid several times. issues

Solution:

  • Fork webview_flutter source code, add a timer on IOS that connects and wakes up gesture every few seconds.

Recommended solutions:

  • Update webview_FLUTTER to 1.0.7 and the FLUTTER SDK to 1.22.3 to resolve the problem.

The Android WebView soft keyboard displays abnormally and the copied text is unavailable

Phenomenon:

Before webView_flutter1.0.0, WebView was used to load THE H5 page with webview_flutter on Android. When the input box was clicked on the H5 page, the soft keyboard could not pop up or fold up, and the long-press text assist control in the H5 page was unavailable.

Solution:

  • This issue was not officially fixed until the FLUTTER SDK1.20. We temporarily fixed the issue by modifying the InputConnection logic with the fork webview_flutter code, but some text features remain.
  • Based on this, we did another thing: we reconstructed all the H5 pages of the main TAB page using FLUTTER. The home page no longer had H5 pages, temporarily avoiding some problems that webview_flutter could not solve.
  • From the start of Flutter SDK1.20, the official hybrid composition scheme is provided. We modified the source of Webview_flutter to make the hybrid composition scheme. And solve the Android WebView soft keyboard pop-up problems, text function is not available.

Recommended solutions:

  • If you are using webview_flutter1.0.0, it is recommended to upgrade the FLUTTER SDK to 1.20 and then modify the official Webview_FLUTTER source to support hybrid Composition. However, when using this scheme, there will be a problem that the app will blink back when you switch to the background and re-enter the app. I will explain how to solve this problem below.
  • If you are using WebView_Flutter1.0.3, update the FLUTTER SDK to 1.22.3 to resolve this problem.

When Android WebView is switched to Hybird Composition, the WebView page is opened, the application is switched to the background and then re-entered the app, which will cause flash back

Phenomenon:

If you are using webview_flutter1.0.0 and have modified the official Webview_FLUTTER source to support hybrid Composition and the Flutter SDK is 1.20, On the Android terminal, the WebView page will be opened, the application will switch to the background and then re-enter the app, which will cause the problem of the app flashing back. issues

Solution:

  • Officially started using two references to store Image objects in Flutterimage, which would cause the reference to the Image to be lost when it was released, As a result, images were not released properly. The authorities then added a list to hold different image objects and traversed the list during cleaning to ensure that all images that existed in history were released properly.
  • Early in the tree view to remove surfaceview triggered PlatformView: : NotifyDestroyed () – > Shell: : OnPlatformViewDestroyed () in a problem on the basis of firm leads to the app in the background, Frames stored in the Image cannot be properly released and updated to a new frame, which eventually triggers frame queue overload and throws an exception crash in the Java layer.
  • According to the official solution, after modifying the Source of FlutterImageView, we recompiled the Flutter Engine and used the compiled to engine product to package the app. The problem was indeed resolved.

Recommended solutions:

  • Upgrade the Flutter SDK to 1.22.3 to resolve this problem.

Android WebView will not be recycled if it is opened repeatedly when switching to Hybird Composition

Phenomenon:

The hybrid Composition solution solves a lot of interaction problems, but it does cause memory leaks, most notably when we repeatedly open the WebView page using Chrome ://inspect to check the webView load. There will be a lot of WebViews that are not recycled. issues

Solution:

  • Find solutions from official issues, but no official only incorporated into 1.22.
  • We incorporated the changes into our local fork’s Flutter engine according to the official solution, recompiled the Flutter engine, and packaged the app using the compile-to-Engine artifacts. The problem was solved.

Recommended solutions:

  • Upgrade the Flutter SDK to 1.22.3 to resolve this problem.

Android WebView switching to Hybird Composition caused memory leakage when opening the WebView page repeatedly

Phenomenon:

After using the hybrid composition scheme, in addition to the official bugs, I did not have a deep understanding of the hybrid composition layer mixing principle. We covered the WebView Widget with a LinearProgressIndicator to fill in the gap between the WebView loading h5, which also caused memory leaks when the FlutterImageView layers were mixed.

Solution:

  • During the LinearProgressIndicator presentation, use a Placeholder screenshot WebView.

Recommended solutions:

  • Upgrade the Flutter SDK to 1.22.3 to resolve this problem.

Webview_flutter 1.0.7 Open webview and exit the Webview page. The phone screen rotates and the APP blinds

Phenomenon:

After upgrading webView_FLUTTER to 1.0.7, open a WebView page before Flutter SDk1.22.1, exit to the previous page, rotate the phone screen, and flash back app. issues

Solution:

  • Find solutions from official issues, but no official only incorporated into 1.22.
  • We incorporated the changes into our local fork’s Flutter engine according to the official solution, recompiled the Flutter engine, and packaged the app using the compile-to-Engine artifacts. The problem was solved.

Recommended solutions:

  • Upgrade the Flutter SDK to 1.22.3 to resolve this problem.

    conclusion

    These are all the problems we encountered with the use of the native WebView in Flutter. From Flutter SDK1.9 to flutter 1.22.3, we tracked and resolved all the problems with the use of the Flutter WebView. No matter we analyze source code for temporary solution or find official solutions from official issues, we have gone through all the pits until now, and finally welcomed the good news of FLUTTER SDk1.22.3. After verification, all the pits we encountered before have been solved by the authorities. We also plan to return the previously locally customized engine to the official Stable branch!