本文为稀土技能社区首发签约文章,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 ,事实上控件并不在烘托方位。
-
HybridComposition
: 经过addView
直接增加原生渠道控件,需求层级覆盖时运用FlutterImageView
承载 Flutter 控件的烘托进行堆叠,原生控件会在烘托方位。
-
TextureLayer
:在烘托方位经过原生的通明PlatformViewWrapper
做容器,然后经过替换 Canvas 将原生控件的纹路烘托到特定 Surface 上,控件不在烘托方位,可是能够经过父容器做事情阻拦。
是不是看完有点懵?不怕后边会有对应的比方解释,不理解也没关系,这一篇是教你怎么选,所以也并不需求真的理解内部是怎么完成。
可是上面介绍的这三种完成也是有前提条件的,比方:
- Flutter 1.2 之前,你只能用
VirtualDisplays
- Flutter 3.0 之前,你只能用
VirtualDisplays
和HybridComposition
- Flutter 3.3 之前,你只能用
TextureLayer
和HybridComposition
- Flutter 3.3 开端,你能用
VirtualDisplays
、TextureLayer
和HybridComposition
是不是觉得有些奇怪,为什么会有奇怪的排列方法?这儿面的故事线大概是这样的:
- 由于
VirtualDisplays
存在接触事情和键盘等问题,所以经过addView
进行原生堆叠的HybridComposition
呈现,处理了手势和键盘等问题 - 由于
HybridComposition
存在一些场景缺点,比方列表卡顿,烘托线程不同步导致闪动等问题,所以VirtualDisplays
得以继续执役 - 3.0 开端默许
VirtualDisplays
和HybridComposition
被替换为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 |
---|---|---|
这儿就不得不提曾经的 issue ,假如你的 WebView 存在接触或许键盘问题就能够经过下述代码来处理,由于正如前面说过, HybridComposition
是经过 addView
的方法增加原生控件,所以能尽或许保存控件本身的特性。
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
而后来 webview_flutter 在更新迭代里默许完成里也修正为了 SurfaceAndroidWebView
,由于 HybridComposition
的确更合适 WebView 的场景,比方 H5 的详情页。
默许判别 | TextureLayer | HybridComposition |
---|---|---|
上面的比方或许还不够典型,接着咱们再看一个典型的比方: 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 |
---|---|
这儿额定需求留意的是:由于隐私方针等原因,现在根本地图结构都需求做必定的隐私相关适配,高德也不例外,所以假如想正常运用 SDK ,就需求留意初始化时的适配问题。
对隐私和权限问题感兴趣能够看 《2022 年 App 上架审阅问题集锦,全面踩坑上线不走失》
-
华为 Flutter 地图插件挑选的则是
HybridComposition
的完成方法,留意下图代码里的initExpensiveAndroidView
,由于现在运用PlatforViewLink
已经不能作为是否运用HybridComposition
的断定标准,3.0 开端有必要显式配置了initExpensiveAndroidView
才是HybridComposition
。
3.0之前 PlatforViewLink
|
3.0之后 PlatforViewLink + initSurfaceAndroidView
|
3.0之后 PlatforViewLink + initExpensiveAndroidVie
|
---|---|---|
HybridComposition |
TextureLayer |
HybridComposition |
对
HybridComposition
具体完成感兴趣的能够了解:混合开发下 HybridComposition 和 VirtualDisplay 的完成与未来演进 和 《1.20 下的 Hybrid Composition 深度解析》
-
百度 Flutter 地图插件选用的是
AndroidView
的完成方法,可是原生端供给了TextureView
和SurfaceView
两种完成挑选,这又产生了不同的组合成果。
3.0之前 | 3.0 | 3.0之后 |
---|---|---|
VirtualDisplays |
TextureLayer ( SurfaceView 方案无法作业) |
VirtualDisplays (SurfaceView)/ TextureLayer (TextureView) |
从下方的 Layout Inspector 能够看到,在 Flutter 3.3 下,百度地图插件假如运用了 MapSurfaceView
就会选用 VirtualDisplays
,而假如运用了 MapTextureView
就会选用 TextureLayer
,这是为什么呢?
SurfaceView | TextureView |
---|---|
前面咱们不是说过,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 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 万起步的授权费用要求,假如你打算用在公司的项目里,那么这个是逃不掉的,由于早晚渠道会打电话联络你缴费,所以在评估时最好将这个费用问题和产品沟通下。
高德 | 百度 | 腾讯 |
---|---|---|
当然,华为的地图服务现在看起来没有商业授权的要求,可是它打包配置麻烦,特别是需求 HMS 的场景,所以假如为了省点钱又不怕麻烦,也能够考虑华为地图。
那有人就要说了,我自己做一个行不可?我比较牛,有数据有能力自己做个简易版地图不就免费了?答案时不可,如下所示,使用渠道会有关于地图相关的资质要求,假如没有你做出来了也上不去。
审阅意见:咱们发现您的使用内含有互联网地图服务相关内容,根据《关于加强互联网地图管理作业的告诉》互联网地图服务单位应当依法取得相应的互联网地图服务测绘资质,并在资质答应的范围内供给互联网地图服务。 修正主张:请弥补供给《测绘资质证书》并在专业范围中注明互联网地图服务;若接入第三方敞开渠道地图服务的,可供给两边合作协议(授权证明),一起需在地图明显方位弥补标明合作单位。
好了,本篇就到这儿结束了,或许相对而言会比之前的内容更“技能性”一些,可是本质还是希望能够协助大家搞清楚 PlatformView
在选型上的差异,最终,假如你还有什么关于 Flutter 工程或许结构的疑问,欢迎留言谈论,