本文为稀土技能社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!

这是 《Flutter 工程化结构挑选》 系列的第四篇 ,就像之前说的,这个系列只是单纯告知你,创立一个 Flutter 工程,或许说搭建一个 Flutter 工程脚手架,应该怎么快速挑选合适自己的功能模块,能够说这是一个指引系列,所以比较合适新手同学。

本篇将着重介绍混合开发里的一些技能选型,趁便额定科普一些坑,看到后边你就会明白为什么要做这一期分类,算是相对偏技能的一期

在 Flutter 里进行混合开发一向都是“痛点”,其间最主要的原因便是:Flutter 有自己独立的烘托引擎,由于 Flutter 控件烘托脱离了渠道控件的 render tree,这也造成了 Flutter 在混合开发上的完成相对杂乱了不少

比较形象的理解:类似于把原生控件塞到 WebView 里烘托。

事实上在 Flutter 里混合开发也分为两种:在 Flutter 里混合原生渠道控件PlatformView)和将 Flutter 混合到原生渠道项目(add-to-app ,本年咱们的主题是 PlatformView ,这其间又以 Android 的 PlatformView 混合原生控件“故事最多”,当然今日咱们不是从头去解说它的技能完成,对前史技能完成感兴趣的能够看之前的文章,今日主要是聊怎么去“选“。

  • Flutter 3.0下的混合开发演进
  • Flutter 深化探索混合开发的技能演进
  • 混合开发下 HybridComposition 和 VirtualDisplay 的完成与未来演进
  • 《1.20 下的 Hybrid Composition 深度解析》
  • 《 Android PlatformView 和键盘问题》

PlatformView

在 Flutter 里混合原生渠道的控件需求经过 PlatformView 进行接入完成,在这方面 iOS 的完成方法一向变化不大,可是在 Android 上不同版别到现在就呈现了三种完成逻辑,所以本篇主要介绍 Android 渠道怎么挑选合适的 PlatformView 方案。

抛开最早期如 flutter_webview_plugin 这种直接进行覆盖原生控件的完成不谈, PlatformView 在 Android 上现在官方供给的就有三种完成方法:

  • VirtualDisplays :类似于一个虚拟显现区域,将虚拟显现区域的内容烘托在一个内存 Surface上,然后同步纹路到 Engine ,事实上控件并不在烘托方位。

Flutter 工程化框架选择 — 混合开发的摸爬滚打

  • HybridComposition : 经过 addView 直接增加原生渠道控件,需求层级覆盖时运用 FlutterImageView 承载 Flutter 控件的烘托进行堆叠,原生控件会在烘托方位。

Flutter 工程化框架选择 — 混合开发的摸爬滚打

  • TextureLayer :在烘托方位经过原生的通明 PlatformViewWrapper 做容器,然后经过替换 Canvas 将原生控件的纹路烘托到特定 Surface 上,控件不在烘托方位,可是能够经过父容器做事情阻拦。

Flutter 工程化框架选择 — 混合开发的摸爬滚打

是不是看完有点懵?不怕后边会有对应的比方解释,不理解也没关系,这一篇是教你怎么选,所以也并不需求真的理解内部是怎么完成。

可是上面介绍的这三种完成也是有前提条件的,比方:

  • Flutter 1.2 之前,你只能用 VirtualDisplays
  • Flutter 3.0 之前,你只能用 VirtualDisplaysHybridComposition
  • Flutter 3.3 之前,你只能用 TextureLayerHybridComposition
  • Flutter 3.3 开端,你能用 VirtualDisplaysTextureLayerHybridComposition

是不是觉得有些奇怪,为什么会有奇怪的排列方法?这儿面的故事线大概是这样的:

  • 由于 VirtualDisplays 存在接触事情和键盘等问题,所以经过 addView 进行原生堆叠的 HybridComposition 呈现,处理了手势和键盘等问题
  • 由于 HybridComposition 存在一些场景缺点,比方列表卡顿,烘托线程不同步导致闪动等问题,所以 VirtualDisplays 得以继续执役
  • 3.0 开端默许 VirtualDisplaysHybridComposition 被替换为 TextureLayer ,可是 HybridComposition 完成依旧保存,在运用时需求显式执行 PlatformViewsService.initExpensiveAndroidView 才能运用,由于 TextureLayer 存在没办法代替原生控件 Canvas 的场景,一起 TextureLayer 要求 Flutter Mini SDK API 23
  • 3.3 开端 VirtualDisplays 完成又回来了,由于需求支持 Mini SDK API 23 以下的场景,一起比方 SurfaceView 机制原因,这类场景 TextureLayer 完成没办法直接兼容,所以 3.3 开端在遇到 SurfaceView 完成时 TextureLayer 会切换为 VirtualDisplays 模式

这儿面固然有完成成本的问题,一起也有社区把控的问题,才造成了这样“混乱”的局势

上面这么说或许有些笼统,咱们再看具体比方,首要看官方的 webview_flutter 完成, 如下表格所示,开始的时分 WebView 插件默许是运用了 AndroidWebView ,也便是 VirtualDisplays 相关的完成;后来有了 HybridComposition 之后就新增了 SurfaceAndroidWebView ,用户在需求时能够根据场景自行切换。

默许判别 VirtualDisplays HybridComposition
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打

这儿就不得不提曾经的 issue ,假如你的 WebView 存在接触或许键盘问题就能够经过下述代码来处理,由于正如前面说过, HybridComposition 是经过 addView 的方法增加原生控件,所以能尽或许保存控件本身的特性。

if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();

而后来 webview_flutter 在更新迭代里默许完成里也修正为了 SurfaceAndroidWebView ,由于 HybridComposition 的确更合适 WebView 的场景,比方 H5 的详情页。

默许判别 TextureLayer HybridComposition
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打

上面的比方或许还不够典型,接着咱们再看一个典型的比方: MapView ,如下所示,现在国内 Flutter 里常见的地图完成有:

  • 华为:huawei_map
  • 高德:amap_flutter_map
  • 百度: flutter_baidu_mapapi_map

尽管他们都是选用了 PlatformView 的完成,可是挑选的完成方法却存在必定差异,而经过这些差异也能够很好比对 PlatformView 完成的差异:

  • 高德 Flutter 插件选用的是 AndroidView 的完成方法,也便是在 3.0 以下是 VirtualDisplays ,在 3.0 以上是 TextureLayer , 从表中的图 2 也能够看到在 Flutter 3.0 MapView 父容器对应的 TextureLayer PlatformViewWrapper
dart 完成 TextureLayer
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打

这儿额定需求留意的是:由于隐私方针等原因,现在根本地图结构都需求做必定的隐私相关适配,高德也不例外,所以假如想正常运用 SDK ,就需求留意初始化时的适配问题。

Flutter 工程化框架选择 — 混合开发的摸爬滚打

对隐私和权限问题感兴趣能够看 《2022 年 App 上架审阅问题集锦,全面踩坑上线不走失》

  • 华为 Flutter 地图插件挑选的则是 HybridComposition 的完成方法,留意下图代码里的 initExpensiveAndroidView ,由于现在运用 PlatforViewLink 已经不能作为是否运用 HybridComposition 的断定标准,3.0 开端有必要显式配置了 initExpensiveAndroidView 才是 HybridComposition

Flutter 工程化框架选择 — 混合开发的摸爬滚打

3.0之前 PlatforViewLink 3.0之后 PlatforViewLink + initSurfaceAndroidView 3.0之后 PlatforViewLink + initExpensiveAndroidVie
HybridComposition TextureLayer HybridComposition

HybridComposition 具体完成感兴趣的能够了解:混合开发下 HybridComposition 和 VirtualDisplay 的完成与未来演进 和 《1.20 下的 Hybrid Composition 深度解析》

  • 百度 Flutter 地图插件选用的是 AndroidView 的完成方法,可是原生端供给了 TextureViewSurfaceView 两种完成挑选,这又产生了不同的组合成果。

Flutter 工程化框架选择 — 混合开发的摸爬滚打

3.0之前 3.0 3.0之后
VirtualDisplays TextureLayerSurfaceView 方案无法作业) VirtualDisplays(SurfaceView)/ TextureLayer(TextureView)

从下方的 Layout Inspector 能够看到,在 Flutter 3.3 下,百度地图插件假如运用了 MapSurfaceView 就会选用 VirtualDisplays ,而假如运用了 MapTextureView 就会选用 TextureLayer ,这是为什么呢

SurfaceView TextureView
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打

前面咱们不是说过,Flutter 在 3.0 的时分经过 TextureLayer 代替了 VirtualDisplays ,而 TextureLayer 的完成方法便是经过 PlatformViewWrapper 来替换 child 的 Canvas 然后提取纹路,可是在某些场景下就会有问题,例如 SurfaceView

简单来说,SurfaceView 是比较特别的场景,本身它具备双缓冲机制,类似于两个 Canvas ,一起在 WMS 有独立的 WindowState , 所以烘托逻辑其实是脱离了本来的 View hierachy ,因此 Flutter 3.0 下的 TextureLayer 的 hook Canvas 完成没办法兼容。

所以在 Flutter 3.3 中 VirtualDisplays 又回来了,作为多年执役的”老将”,当运行渠道低于 23 或许原生控件是 SurfaceView 时,就会继续降级选用 VirtualDisplays 的相关完成,这也算是折中的完成

Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打

假如对这部分感兴趣的能够查阅 Flutter 3.0下的混合开发演进 / Flutter 深化探索混合开发的技能演进

所以现在知道为什么要做这一期了吧?Flutter 的 PlatformView 完成由于前史包袱留下了许多“坑”,不理清楚这些坑,很或许就会让你在遇到问题时找不到方向,总结一下:

  • VirtualDisplays 老骥伏枥,选用的是虚拟显现提取纹路的方法,或许存在手势和键盘问题,合适列表和小控件场景,在 3.0 版别中缺席
  • HybridComposition 在 1.2 版别之后呈现,由于是经过 addView 和层级堆叠完成混合,能尽或许确保控件的“原汁原味”,可是功能开支会比较大,不合适列表里运用,在 3.0 之后需求显式调用 initExpensiveAndroidView
  • TextureLayer 在 3.0 版别开端呈现,经过 Hook 住控件 Canvas 的方法完成纹路提取,可是需求 miniSDK 23 ,适用于代替 VirtualDisplays 的场景,可是在 3.3 开端遇到 SurfaceView 时会降级为 VirtualDisplays

其实我有预见,在之后的版别这部分逻辑还会呈现变化,可是或许 3.0 和 3.3 的发布相同,并不会将这种改变放在 release note 里。

最终,这儿额定介绍一个关于地图的小知识点,现在国内三大地图 SDK 厂商都有商用 5 万起步的授权费用要求,假如你打算用在公司的项目里,那么这个是逃不掉的,由于早晚渠道会打电话联络你缴费,所以在评估时最好将这个费用问题和产品沟通下。

高德 百度 腾讯
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打
Flutter 工程化框架选择 — 混合开发的摸爬滚打

当然,华为的地图服务现在看起来没有商业授权的要求,可是它打包配置麻烦,特别是需求 HMS 的场景,所以假如为了省点钱又不怕麻烦,也能够考虑华为地图。

Flutter 工程化框架选择 — 混合开发的摸爬滚打

那有人就要说了,我自己做一个行不可?我比较牛,有数据有能力自己做个简易版地图不就免费了?答案时不可,如下所示,使用渠道会有关于地图相关的资质要求,假如没有你做出来了也上不去。

审阅意见:咱们发现您的使用内含有互联网地图服务相关内容,根据《关于加强互联网地图管理作业的告诉》互联网地图服务单位应当依法取得相应的互联网地图服务测绘资质,并在资质答应的范围内供给互联网地图服务。 修正主张:请弥补供给《测绘资质证书》并在专业范围中注明互联网地图服务;若接入第三方敞开渠道地图服务的,可供给两边合作协议(授权证明),一起需在地图明显方位弥补标明合作单位。

好了,本篇就到这儿结束了,或许相对而言会比之前的内容更“技能性”一些,可是本质还是希望能够协助大家搞清楚 PlatformView 在选型上的差异,最终,假如你还有什么关于 Flutter 工程或许结构的疑问,欢迎留言谈论,