Flutter AndroidPlatformView
https://guoshuyu.cn/home/wx/Flutter-P3.html
https://juejin.cn/post/7093858055439253534#heading-8
首先看下 Android 端 PlatformView 创建过程。(以下分析基于flutter 3.10版本实现)
1 | // PlatformView 定义 |
flutter端调用有两种方式,一种是 PlatformViewLink
(对应native 端实现是Hybrid composition,后面讲):
1 | Widget build(BuildContext context) { |
另一种是 AndroidView
(对应native 端实现是Virtual display,后面讲):
1 | Widget build(BuildContext context) { |
我们知道 flutter 和 native 交互都是通过 channel 进行,PlatformView 创建也不例外。创建 PlatformView 首先会调用 PlatformViewsChannel
类中 parsingHandler
对象的 create
方法。create
方法中会根据 hybrid
参数为 true
时调用 PlatformViewsController.createForPlatformViewLayer
为 flase
时调用 PlatformViewsController.createForTextureLayer
,这两个方法里会决定 PlatformView 的实现方式。
先看下hybrid
参数是哪里来的。Flutter 端创建的时候不管是 AndroidView 方式,还是 PlatformViewLink 方式,都会创建一个 AndroidViewController 对象,AndroidViewController 对象负责通过 channel 和 native 端通信。对象,AndroidViewController 有三个实现,分别是 TextureAndroidViewController、SurfaceAndroidViewController、ExpensiveAndroidViewController。TextureAndroidViewController 和 SurfaceAndroidViewController 中 hybrid
值为 false
,ExpensiveAndroidViewController 中 hybrid
值为 true
。
回到 PlatformViewsController 类。createForPlatformViewLayer()
方法很明显,采用 HybridComposition
实现。createForTextureLayer()
方法并不一定采用 TextureLayer 实现(因为 TextureLayer 需要依赖硬件加速,所以sdk版本需要23级以上,而且 TextureLayer 不支持 SurfaceView,所以如果 PlatformView 中包含 SurfaceView 也无法使用 TextureLayer 实现)。以下为createForPlatformViewLayer
方法中的注释:
1 | // The newer Texture Layer Hybrid Composition mode isn't suppported if any of the |
所以如果不支持 TextureLayer 实现的话会降级为 HybirdComposition 实现或 VirtualDisplay 实现。具体降级为哪个实现是根据创建是的 hybridFallback
参数来确定。
SurfaceAndroidViewController 的 hybridFallback
参数为 true
,如果不支持 TextureLayer 会降级为 HybirdComposition 实现。
总结:
TextureLayer实现
- sdk 版本为 23 及以上,并且 NativeView 中不含有 SurfaceView,flutter 端通过 AndroidView 调用,或者通过 PlatformViewLink 调用并且
onCreatePlatformView
方法中返回TextureAndroidViewController 或 SurfaceAndroidViewController
HybirdComposition
- sdk 版本为 23 以下,或 NativeView 中含有 SurfaceView,flutter 端通过 PlatformViewLink 调用并且
onCreatePlatformView
方法中返回 SurfaceAndroidViewController - flutter 通过 PlatformViewLink 调用并且
onCreatePlatformView
方法中返回ExpensiveAndroidViewController
VirtualDisplay实现
- sdk 版本为 23 以下,或 NativeView 中含有 SurfaceView,flutter 端通过 AndroidView 调用,或者通过 PlatformViewLink 调用并且
onCreatePlatformView
方法中返回TextureAndroidViewController 或 SurfaceAndroidViewController
Flutter AndroidPlatformView 最早是采用 VirtualDisplay 实现的。VirtualDisplay 实现大致原理是创建一块虚拟屏幕,把 AndroidView 绘制到虚拟屏幕上,
VirtualDisplay实现:
VD简单来说就是使用 VirtualDisplay 渲染原生控件到内存,然后利用 id 在 Flutter 界面上占用一个相应大小的位置,最后通过 id 关联到 Flutter Texture 里进行渲染。
问题:控件不是被真实渲染,容易有触摸和键盘等问题
HybirdComposition实现:
1.2 版本开始支持 HC,简单说就是直接把原生控件覆盖在 Flutter 上进行堆叠,如果出现 Flutter Widget 需要渲染在 Native Widget 上,就采用新的 FlutterImageView 来承载新图层。好处是原生视图是直接显示渲染,坏处就是在 Android 10 之前存在 GPU->CPU->GPU的性能损耗。
另外因为此时原生控件是直接渲染,所以需要在原生的平台线程上执行,这和 Flutter 的 UI 线程就存在线程同步问题,所以在此之前一些场景下会有画面闪烁 bug 。
问题:直接堆叠控件,会有性能开销和线程同步问题,某些场景容易出现闪烁和卡顿
TextureLayer实现:
3.0 版本开始支持 TLHC 模式,最初的目的是取代上面这两种模式,奈何最终只能共存下来,该模式下控件虽然在还是布局在该有的位置上,但是其实是通过一个 FrameLayout 代理 onDraw 然后替换掉 child 原生控件的 Canvas 来实现混合绘制。
但是这种实现天然不支持 SurfaceView ,因为 SurfaceView 是双缓冲机制,所以通过 parent 替换 Canvas 的实现并不支持。
问题:不支持 SurfaceView ,对于使用 SurfaceView 的播放器、地图等插件会有兼容性问题。
Flutter AndroidPlatformView