假如你是从 2018 年开端运用 Flutter ,那么相信你关于 Flutter 在混合开发的支撑进程应该会有一个深化的体会,假如你没尽力过这个时期,不要忧虑,经过我过往 PlatformView 的相关文章,你也能够有一个清晰的感触:

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

总而言之,现在 Flutter 关于 PlatformView 的支撑,特别是在 Android 渠道上,只能用一个字来描绘:「乱」。

Flutter III 之你不知道的 PlatformView 的混乱之治

这个「乱」不只是体现在 API 和底层完成计划上,更体现在你遇到 issue 时,不确定到底是由于什么引起的困惑上,由于现在 Flutter 在 Android 渠道的 PlatformView 会依据不同的 SDK 版别和场景进行「兜底」兼容,存在各种历史包袱。

其实我已经不是很想写这方面的内容了,可是怎么办总有人问,那么本篇就来个总结式科普。

现在活跃在 Android 渠道的 PlatformView 支撑首要有以下三种:

  • Virtual Display (VD)
  • Hybrid Composition (HC)
  • Texture Layer Hybrid Composition (TLHC)

能够看到官方都已经为我们界说好了简称 VD、HC、TLHC ,有了简称也方便我们提 issue 时沟通,毕竟每次在讨论时都用全称很费劲:

由于你需求不停指出你用的是什么形式,然后在什么形式下正常or不正常,别的知道这些简称最大的作用便是看 issue 时不模糊

那么,接下来首要简略介绍它们的区别:

VD

VD简略来说便是运用 VirtualDisplay 烘托原生控件到内存,然后利用 id 在 Flutter 界面上占用一个相应大小的位置,最后经过 id 关联到 Flutter Texture 里进行烘托。

Flutter III 之你不知道的 PlatformView 的混乱之治

问题也很明显,由于控件不会真实存在烘托的位置,所以此刻的点击和对原生控件的操作,其实都是需求由 Flutter 这个 View 进行二次转发,别的由于控件是烘托在内存里,所以和键盘交互需求经过二级代理处理,这就产生了各种键盘输入的异常问题。

键盘问题突出在不同版别的 Android 兼容上。

HC

1.2 版别开端支撑 HC,简略说便是直接把原生控件覆盖在 Flutter 上进行堆叠,假如呈现 Flutter Widget 需求烘托在 Native Widget 上,就选用新的 FlutterImageView 来承载新图层。

Flutter III 之你不知道的 PlatformView 的混乱之治

好处是原生视图是直接显示烘托,害处便是在 Android 10 之前存在 GPU->CPU->GPU的功能损耗。

别的由于此刻原生控件是直接烘托,所以需求在原生的渠道线程上履行,这和 Flutter 的 UI 线程就存在线程同步问题,所以在此之前一些场景下会有画面闪耀 bug 。

TLHC

3.0 版别开端支撑 TLHC 形式,最初的目的是替代上面这两种形式,怎么办终究只能共存下来,该形式下控件尽管在仍是布局在该有的位置上,可是其实是经过一个 FrameLayout 代理 onDraw 然后替换掉 child 原生控件的 Canvas 来完成混合制作。

Flutter III 之你不知道的 PlatformView 的混乱之治

所以看到此刻上图 TextView 里没有了内容,由于 TextView 里的 Canvas 被替换成 Flutter 在内存里创立的 Canvas

可是这种完成天然不支撑 SurfaceView ,由于 SurfaceView 是双缓冲机制,所以经过 parent 替换 Canvas 的完成并不支撑。

总结

上述便是这现在三种形式的简略描绘和对比,假如看不明白,能够经过前面的历史文章进行了解,总结下以下它们的首要问题:

  • VD : 控件不是被真实烘托,简单有接触和键盘等问题
  • HC: 直接堆叠控件,会有功能开销和线程同步问题,某些场景简单呈现闪耀和卡顿
  • TLHC:不支撑 SurfaceView ,关于运用 SurfaceView 的播放器、地图等插件会有兼容性问题。

所以这也是为什么 1.2 HC 出来之后,VD 还在持续被投入运用,以至于 TLHC 发布之后,依然没能彻底替代 VD 和 HC 的首要原因,由于现在它们都不是最优解。

而从现在的情况下,PlatformView 也成了 Android 渠道的沉重包袱,由于多种底层形式在一起作业,而且还在互相「兼容」。

API

那么回归到 API 上,在现在 3.0+ 的 Flutter 上同样对应有三个 API ,可是这三个 API 并不是直接对应上述三种形式:

  • initAndroidView :默认情况下会运用 TLHC 形式,当 SDK 低于 23 或许存在 SurfaceView 的时分,会运用 VD 形式兼容
  • initSurfaceAndroidView : 默认情况下会运用 TLHC 形式,当 SDK 低于 23 或许存在 SurfaceView 的时分,会运用 HC 形式兼容
  • initExpensiveAndroidView: 强行彻底运用 HC 形式

看到没有,这里有一个问题便是:你其实没办法自动操控是 TLHC 仍是 VD ,关于 HC 你却是能够强行指定

别的,不知道你注意到没有,不管是 initAndroidView 仍是 initSurfaceAndroidView ,它们都或许会在升级到新版别时运用 TLHC 形式,也便是假如你的 Plugin 没有针对性做更新,那么或许会在不知觉的情况下换了形式,从而有或许呈现 bug

例如 TLHC 形式:

  • 关于 SurfaceView 的不支撑存在一些特殊情况,假设一开端 PlatformView 创立时不存在 SurfaceView ,可是后续又添加了 SurfaceView ,那么该形式将无法正常作业 #109690。
  • 关于 TextureView 场景,有时分会呈现不正常更新的异常情况#103686 。

现在你看出 PlatformView 的混乱了吧?从底层完成的不一致,到 API 再不同版别下不同的行为改变,这便是现在 Android 在 PlatformView 支撑下的混乱生态,一起假如你关于现在 PlatformView 存在的问题刚爱好,能够查阅以下相关 issue:

  • #103686
  • #109690
  • #112712
  • #130692

所以,现在的 Android PlatformView 就给我一种既视感,好比魔兽国际里的平行分支:

  • 阴间吼怒喝下了恶魔之血,绿皮吼爷打爆深渊领主玛诺洛斯
  • 阴间吼怒回绝喝恶魔之血,橙皮吼爷打爆深渊领主玛诺洛斯

尽管都是打爆了玛诺洛斯,尽管吼爷结局都相同扑街,可是中间的剧情走向仍是有着极大的分歧,所以只能寄希望未来的国际线能够正常「收束」,能有一位「伯瓦尔」来结束这个混乱之治的时代。

Flutter III 之你不知道的 PlatformView 的混乱之治

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。