对采用过 Flutter 的合作开发而言,假如对在 Flutter 混和合作开发中,透过 PlatformView 网络连接原生植物命令行的形式并不孤单,而假如你从 Flutter 1.20 以后就早已开始采用 Flutter ,所以假如对 Android 上 PlatformView 的各式各样新体验难题有过真切的感受,比如说:<a href=”https://juejin.cn/post/6858473695939084295″> WebView 里插入按键的难题。
❝⚠️特别注意:variations有精采
❞从两个难题早已开始
碰巧前段时间一名好友在 Flutter 2.10.1 上采用 webview_flutter 和 flutter_pdfview 试验时再次出现了如下表所示的难题:
「因此话虽如此那个难题来给我们科学普及下 Flutter 里 PlatformView 与此同时实现的社会变迁和今后修正」,具体而言那个难题的直接其原因其原因是:
❝virtual displayes 和 hybrid composition 三种 PlatformView 与此同时实现混和采用。
❞即使从 Flutter 2.10 早已开始,非官方的 Plugin 如 webview_flutter 默都是采用 hybrid composition的与此同时实现,而服务器端的 flutter_pdfview 现阶段却是采用从前的 virtual display ,这就再次出现了三种 PlatformView 与此同时实现与此同时再次出现的情形。
总之,非官方在 2.10.2 版的 #31390 上复原了那个难题, 难题的其原因是:「当 rasterizer 各项任务运转相同的缓存时,GrContext 会被再次建立,从而引致 texture 变为没初始化的状况,从而多次重复初始化 attachToGLContext 引致崩盘」。
❝因此先期非官方复原那个难题,是在 attachToGLContext 以后,假如 texture 早已 attach 过,就先初始化 detachFromGLContext 展开释放出来,从而防止了初始化 context 的难题。
❞但从难题上看,其实那个难题并不是 2.10 才会再次出现,而是只要在 SurfaceTextureWrapper 那个对象存在时 ,混和采用 virtual displayes 和 hybrid composition 就能引发那个 bug 。
❝SurfaceTextureWrapper 是非官方用于处理同步的难题,即使当 SurfaceTexture被释放出来时,由于 SurfaceTexture.release 是在 platform 缓存被初始化,而 attachToGLContext 是在 raster 缓存被初始化,相同缓存初始化时可能引致:「当 attachToGLContext 被初始化时 texture 早已被释放出来了,因此需要 SurfaceTextureWrapper 用于与此同时实现 Java 里同步锁的效果」。
❞因此假如在低版不想升级,所以可以选择所有 Plugin 都采用 virtual display 模式或者 hybrid composition 模式,比如说 webview_flutter 就提供了 WebView.platform 用于用户自由选择 PlatformView 的渲染模式。
「总之一般情形下我是更建议我们现阶段都采用 hybrid composition 模式,虽然三种模式都有潜在难题,但相比起来现阶段 virtual display 带来的性能和按键难题会让人更难以接受」。
区别和重构
其实在以后的 《 Hybrid Composition 深度解析》 里就介绍过它们与此同时实现的区别,这里再结合上面的难题,从不一样的角度介绍下它们的与此同时实现差异和社会变迁。
VirtualDisplay
一般 dart 代码里直接采用 AndroidView 的我们就可以简单认为是采用 virtual display ,比如说flutter_pdfview 1.2.2 版 , 这种与此同时实现形式是 「透过将 And
❝VirtualDisplay 类似于两个虚拟显示区域,需要结合 DisplayManager 一起初始化,一般在副屏显示或者录屏场景下会用到。VirtualDisplay 会将虚拟显示区域的内容渲染在两个 Surface上。
❞关于 virtual display 与此同时实现,假如你需要对应路径去调试难题,可以参看如下表所示流程:
HybridComposition
采用 hybrid composition 相对会比直接采用 AndroidView 在代码上更复杂一点, 需要采用到PlatformViewLink、 AndroidViewSurface 和 PlatformViewsService 这三个对象,具体而言我们要建立两个 dart 命令行:
透过 PlatformViewLink 的 viewType 注册了两个和原生植物层对应的注册名称,这和以后的 PlatformView 注册一样;然后在 surfaceFactory 返回两个 AndroidViewSurface 用于处理绘制和接收触摸事件;最后在 onCreatePlatformView 方法采用 PlatformViewsService 初始化 AndroidViewSurface 和初始化所需要的参数,与此同时透过 Engine 去触发原生植物层的显示。假如透过上面的难题来做个直观的对比,就会是如下表所示图所示的变化:
采用 hybrid composition 之后, 「PlatformView 是透过 FlutterMutatorView 把原生植物命令行 addView 到 FlutterView 上,然后再透过 FlutterImageView 的能力去与此同时实现图层的混和」,简单解释是:
rmView 上渲染 Flutter 自己的 Widget 时,Flutter 就会透过再叠加两个 FlutterImageView 来承载那个 Widget 。
❞举个例子,如下表所示图所示,其中:
两个灰色的 Re 是原生植物的 TextView;蓝色、黄色、红色的是 Flutter 的 Text ;从渲染结果上可以看到:
灰色的原生植物 TextView 透过 PlatformView 直接就透过原生植物的 addView 方法添加到 FlutterView 上;而红色的 Flutter 的 Text 命令行即使和 PlatformView 没交集,因此却是 Flutter 原本的渲染逻辑;黄色和蓝色的 Flutter 命令行,即使和 PlatformView 有交集,因此透过新的 FlutterImageView 做承载渲染。采用 hybrid composition 后,在 Engine 去 SubmitFrame 时,会透过 current_frame_view_count 去对每个 view 画面展开规划处理,然后会透过判定区域内是否需要 CreateSurfaceIfNeeded 函数,最终触发原生的 createOverlaySurface 方法去建立 FlutterImageView。
假如有需要调试 hybrid composition 相关功能的,可以参考如下表所示路径, 和 virtual display 相同之处是在 create 之后的路径产生了变化 , 更多详细演示可见:https://juejin.cn/post/6858473695939084295#heading-2
结论
因此可以看到,「hybrid composition 保留了更多的原生植物命令行效果,也节省了渲染成本」 ,总之现阶段 PlatformView 还有两个比较尖锐的难题,例如#95343 的闪动难题,那个难题看来在今后会透过更改渲染形式和纹理优化来解决。
是的,还其原因是性能等难题,因此「新的 PlatforView 与此同时实现来又要来了,从上面提到的 #31198已经合并可以猜测,下两个稳定版中,现在的 virtual displayes 与此同时实现将不复存在,从而替代的是透过新的 TextureLayer 与此同时实现,今后不排除 hybrid composition 也会被取消,不知道我们此刻心情如何?」
简单说是:
新的 PlatformViewWrapper 会替换掉原本 virtual display 里 SurfaceTextureWrapper相关的逻辑,通ition 现阶段看起里仅是更换了称谓,只要核心逻辑没大变动;而假如今后 PlatformViewWrapper 的与此同时实现效果良好 ,可以猜测 hybrid composition 模式也会从而退出历史舞台,因此唯有感慨, Flutter 的技术重构速度真的好快。