Flutter WebView 小记

转载请注明原文链接:
http://t.csdn.cn/3OJpw
https://juejin.cn/post/7209826725366628409

前置条件

Flutter WebView 的更新频率是很快的,也许文中提到的问题,在后面的版本不会有,所以先说明下环境和版本。
此外,使用 WebView 的方式也可能是出现这些异常的因素,使用 FlutterBoost、嵌套、写死高度等。

image.png

image.png

具体问题

  1. 鸿蒙系统、部分oppo、vivo系统,使用 loadHtmlString 加载含图片的本地富文本出现闪退;
  2. 针对 Android 使用 displayWithHybridComposition 的方式加载存在“第二次打开Flutter页时,出现上次 WebView 残留问题“;

问题定位和解决方案

白屏和闪退
  • 定位:因为上述系统都是“阉割版”升级,系统版本升级到了 23 但是 WebView 内核并没有同步到 Google 官方最新版本,直接导致 TextureSurfaceView 崩溃(参考官方文档:texture-layer-hybrid-composition);

  • 解决方案:

    if (WebViewPlatform.instance is WebKitWebViewPlatform) {
      return WebViewWidget(controller: checkedController);
    } else {
      return WebViewWidget.fromPlatformCreationParams(
        params: AndroidWebViewWidgetCreationParams(
          controller: checkedController.platform,
          //针对鸿蒙系统使用 displayWithHybridComposition 为 true
          displayWithHybridComposition: Constants.isHarmony,
        ),
      );
      // return AndroidWebViewWidget(
      //   AndroidWebViewWidgetCreationParams(
      //     controller: checkedController.platform,
      //     displayWithHybridComposition: true,
      //   ),
      // ).build(context);
    }
    
残留或内存没有释放
  • 定位:这一点没有找到官方解释,有可能是 FlutterBoost 影响了生命周期导致没有释放,也有可能是使用 displayWithHybridComposition 时,Android WebView 是一个单例,也许两者都有,总之是暂未有定论。(之前看到 FlutterBoost 更新说明提到: [Android] Fixes HybridCompositon does not work (#1743),然并卵)

  • 解决方案:(有两个思路)

    • WebView 是单例,那么针对使用Hybird的情况,在每个Flutter页面初始化一个空的 WebView 就可以去掉残留(这个是个坏的解决方案)。

    • 使用 WebViewFlutterAndroidExternalApi ,在原生端获取到Flutter端的WebView,在 Activity onDesroty 时释放 WebView,如下:

      override fun onDestroy() {
          Ulog.i("ToFlutterContainerActivity onDestroy in")
      //exclusiveAppComponent?.
          FlutterNativeBridge.mEngine?.also { flutterEngine ->
                  FlutterNativeBridge.invokeFlutterWebViewIdentifierList { webViewIds ->
                      webViewIds.forEach { identifier ->
                              WebViewFlutterAndroidExternalApi.getWebView(
                                  flutterEngine, identifier
                              )?.also { webView ->
                          ULog.i("ToFlutterContainerActivity in webView.destroy: $identifier")
                         // webView.destroy()
                          if(webView.parent is ViewGroup){
                              ULog.i("ToFlutterContainerActivity in webView.removeView: $identifier")
                              (webView.parent as ViewGroup).removeView(webView)
                              webView.destroy()
                          }
                      }
                  }
              }
          }
          super.onDestroy()
      }
      

小结

有两个点

一个是混编如果可以最好用官方的试试,FlutterBoost 不太放心,而且存在很多和官方设计思维不太匹配的问题;

一个是 WebView 的嵌套实现,由于时间问题,其实不应该这么简单的计算方式,可以试试这个extended_sliver的思路

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值