关于 Flutter 混合 PlatformView
的完结已经介绍过两次,跟着 5 月份谷歌 IO 的接近,新的 PlatformView
完结应该也会随之而来,本次就自始至终来一个具体的关于 PlatformView
的演进总结。
Flutter 作为新一代的跨渠道框架,经过自定义烘托引擎的立异大大提高了跨渠道的功能和一致性,但也正是由于这点, 相比之下 Flutter 在混合开发时关于原生控件的支撑成本更高。
Flutter 混合开发的难点
首要 Flutter 在混合开发中最大的难点就在于它独立的烘托引擎,举一个不是很恰当的比方:
Flutter 里混合开发相似与把原生控件烘托到
WebView
里。
大致上在 Flutter 里混合开发的感觉便是这样,由于 Flutter UI 不会转换为原生控件,而是由 Flutter Engine 运用 Skia 直接烘托在 Surface
上。
所以 Flutter 在最早出来时并不支撑 WebView
或 MapView
这些常用的控件,这也导致了其时 Flutter 一度的风评不大好,所以衍生出了第一代非官方的混合开发支撑,例如: flutter_webview_plugin
。
在官方 WebView
控件支撑出来之前 ,第三方是直接在 FlutterView
上掩盖了一个新的原生控件,利用 Dart 中的占位控件来传递方位和巨细。
Flutter 里简直一切烘托都是烘托到
FlutterView
这样一个单页面上,所以直接掩盖一个新的原生WebView
只能说缓解燃眉之急。
如下图,在 Flutter 端 push
出来一个 设定好方位和巨细 的 SingleChildRenderObjectWidget
,然后得到需求显现的巨细和方位,将这些信息经过 MethodChannel
传递到原生层,在原生层 addContentView
一个指定巨细和方位的 WebView
。
这样看起来就像是在 Flutter 中增加了 WebView
,但实际这样的操作只能说是“救急”,由于这样的行为脱离了 Flutter 的烘托树,其间一个问题便是:
当你跳转 Flutter 其他页面的时分会被当时原生的
WebView
挡住;而且打开页面的动画时Appbar
和WebView
难以保持一致,由于Appbar
和WebView
是出于两个动画体系和烘托体系。
就比方打开了新的 Flutter UI 2 页面,可是由于它仍是在 FlutterView
内,所以它会被 WebView
所遮挡。
可是这个“占位”显现的思路,也起到了必定的作用,在后续 Flutter 支撑原生 PlatformView
上起到了带头的作用。
Flutter 开始支撑原生控件
为了让 Flutter 真实走向大众化,官方开始推出了官方基于 PlatformView
的系列完结,比方: webview_flutter
,而这个完结 “缝缝补补” 也被沿用至今,成了 Flutter 接入原生的方法 之一。
Android
在 PlatformView
的整个完结中 Android 坑一直是最多的,由于一开始 Android 上首要是经过 AndroidView
做完结这项作业,而它的 Virtual Displays 完结其实并不友好。
在 Flutter 中会将 AndroidView
需求烘托的内容制作到 VirtualDisplays
中 ,然后在 VirtualDisplay
对应的内存中,制作的画面就能够经过其 Surface
获取得到。
VirtualDisplay
相似于一个虚拟显现区域,需求结合DisplayManager
一同调用,一般在副屏显现或许录屏场景下会用到,在VirtualDisplay
里会将虚拟显现区域的内容烘托在一个Surface
上。
如上图所示,简略来说便是原生控件的内容被制作到内存里,然后 Flutter Engine 经过相对应的 textureId
就能够获取到控件的烘托数据并显现出来,这个过程 AndroidView
这个占位控件供给了 size、offset 等方位和巨细参数。
经过从 VirtualDisplay
获取纹路,并将其和 Flutter 原有的 UI 烘托树混合,使得 Flutter 能够在自己的 Flutter Widget tree 中以图形方法刺进 Android 原生控件。
iOS
在 iOS 渠道上就不运用相似 VirtualDisplay
的方法,而是经过将 Flutter UI 分为两个透明纹路来完结组合:一个在 iOS 渠道视图之下,一个在其上面。
所以这样的优点便是:
- 需求在 “iOS渠道” 视图下方呈现的Flutter UI,终究会被制作到其下方的纹路上;
- 而需求在 “渠道” 上方呈现的 Flutter UI,终究会被制作在其上方的纹路;
iOS 上它们只需求在最终组合起来就能够了,一般这种方法更好,由于这意味着 Native View 能够直接增加到 Flutter 的 UI 层次结构中,可是可惜一开始 Android 渠道并不支撑这种模式。
问题
尽管前面能够运用 VirtualDisplay
将 Android 控件嵌入到 Flutter UI 中 ,但这种 VirtualDisplay
这种介入还有其他麻烦的问题需求处理。
接触作业
默许状况下, PlatformViews
是没方法接收接触作业,由于 AndroidView
其实是被烘托在 VirtualDisplay
中 ,而每逢用户点击看到的 "AndroidView"
时,其实他们就真实”点击的是正在烘托的 Flutter
纹路 ,用户发生的接触作业是直接发送到 Flutter View 中,而不是他们实际点击的 AndroidView
。
所以 AndroidView
运用 Flutter Framework 中检测用户的接触是否在需求的特殊处理的区域内:
当接触成功时会向 Android embedding 发送一条音讯,其间包括 touch 作业的具体信息。
这就变成有些本末倒置,接触作业从原生-Flutter-原生,中心的转化导致某些信息被丢掉,也导致了响应的延迟。
文字输入
AndroidView
是无法获取到文本输入,由于 VirtualDisplay
地点的方位会始终被认为是 unfocused
的状况。
所以需求做一套代理来处理 InputConnections
做输入,乃至这个行为在 WebView
上更杂乱,由于 WebView
具有自己内部的逻辑来创建和设置输入连接,而这些输入连接并没有彻底遵循 Android 的协议。
同步问题
另外还需求处理各种同步问题,比方官方就创建了一个 SurfaceTextureWrapper
用于处理同步的问题。
由于当承载 AndroidView
的 SurfaceTexture
被释放时,由于 SurfaceTexture.release
是在 platform 线程被调用,而 attachToGLContext
是在 raster 线程被调用,不同线程调用时或许导致:当 attachToGLContext
被调用时 texture 已经被释放了,所以需求 SurfaceTextureWrapper
用于完结 Java 里同步锁的作用。
Flutter Hybrid Composition
所以阅历了 Virtual Display 的摧残之后,官方终于在后续推出了更为合理的完结。
完结逻辑
hybrid composition 的呈现给 Flutter 供给了一种新的混合思路,那便是直接把原生控件增加到 Flutter 里一同组合烘托。
首要简略介绍下运用,比起 Virtual Display 直接运用 AndroidView
,hybrid composition 相对会杂乱一点点,dart 里运用到 PlatformViewLink
、AndroidViewSurface
、 PlatformViewsService
这三个对象。
正常在 dart 层面,运用 hybrid composition 接入原生控件:
- 经过
PlatformViewLink
的viewType
注册了一个和原生层对应的注册称号,这和之前的PlatformView
注册相同; - 然后在
surfaceFactory
返回一个AndroidViewSurface
用于处理制作和接收接触作业,一起也是一个相似占位的作用; - 最终在
onCreatePlatformView
方法运用PlatformViewsService
初始化AndroidViewSurface
和初始化所需求的参数,一起经过 Engine 去触发原生层的显现。
Widget build(BuildContext context) {
// This is used in the platform side to register the view.
final String viewType = 'hybrid-view-type';
// Pass parameters to the platform side.
final Map<String, dynamic> creationParams = <String, dynamic>{};
return PlatformViewLink(
viewType: viewType,
surfaceFactory:
(BuildContext context, PlatformViewController controller) {
return AndroidViewSurface(
controller: controller,
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
onCreatePlatformView: (PlatformViewCreationParams params) {
return PlatformViewsService.initSurfaceAndroidView(
id: params.id,
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: StandardMessageCodec(),
)
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
..create();
},
);
}
看起来好像是把一个 AndroidView
完结的作业变得相对杂乱了,可是其实 hybrid composition 的完结相比其实更好理解。
运用 hybrid composition 之后, PlatformView
就直接经过 FlutterMutatorView
(一个特殊的 FrameLayout
) 把原生控件 addView
到 FlutterView
上,然后再经过 FlutterImageView
的才能去完结多图层的混合。
不理解吗?没事,咱们后面会具体介绍,先简略解说便是:
Flutter 只直接经过原生的
addView
方法将PlatformView
增加到FlutterView
,这就不需求什么surface
烘托再去获取的开支,而当你还需求再PlatformView
上烘托 Flutter 自己的 Widget 时,Flutter 就会经过再叠加一个FlutterImageView
来承载这个 Flutter Widget 。
深化比方详解
接下来让咱们从实际比方去理解 Hybrid Composition ,结合 Andriod Studio 的 Layout Inspector,并敞开手机的制作鸿沟来看会更直观。
如下代码所示,一般状况下咱们运转之后会看到一片黑色,由于这时分 FlutterView
只要一个 FlutterSurfaceView
的子控件存在,此刻尽管咱们画面上是有一个 Flutter 的赤色 RE
文本控件 ,不过由于是由 Flutter 直接在 Surface 直接制作,所以 Layout Inspector 看不到只显现黑色。
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment.center,
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
)
],
)
此刻咱们增加一个经过 Hybrid Composition 完结一个原生的 TextView
控件,经过 PlatformView
在 Flutter 上烘托出一个灰色 RE
文本。
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment(-0.6, -0.6),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment.center,
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
)
],
)
能够看到,如上图所示,在咱们的显现布局鸿沟上能够清晰看到它的信息:
TextView
经过FlutterMutatorView
被增加到FlutterView
上被直接显现出来。
所以 TextView
是直接在原生代码上被 add 到 FlutterView
上,而不是提取纹路,另外能够看到,左边栏里多了一个 FlutterImageView
,而且之前看不到的 Flutter 控件赤色 RE
文本也呈现了,布景也变成了 Flutter 上的白色。
咱们先暂时疏忽新呈现的 FlutterImageView
和 Flutter UI 能够呈现在 Layout Inspector 的原因,留到后面再来剖析,此刻咱们再新增加以一个赤色的 Flutter RE
控件到 Stack
里,坐落 PlatformView
的灰色 RE
下。
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment(-0.4, -0.4),
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
),
Align(
alignment: Alignment(-0.6, -0.6),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment.center,
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
)
],
)
如上图所示,能够看到布局和烘托作用正常,Flutter 的赤色 RE
被上面的 PlatformView
灰色 RE
遮挡了部分,这是契合代码的烘托作用。
假如这时分咱们把新增加的第二个赤色 RE
放到灰色 PlatformView
灰色 RE
上,会发生什么状况?
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment(-0.6, -0.6),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment(-0.4, -0.4),
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
),
Align(
alignment: Alignment.center,
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
)
],
)
能够看到赤色的 RE
成功被烘托到灰色 RE
上 ,而之所以能够烘托上去的原因,是由于这个和 PlatformView
有交集的 Text
,被烘托到一个新增的 FlutterImageView
控件上, 也便是 Flutter 判断了此刻新赤色 RE
文本需求烘托到 PlatformView
上,所以增加了一个 FlutterImageView
用于承载这部分烘托内容。
假如这时分挪动第二个赤色的 RE
让它和 PlatformView
没有交集,可是仍是在 Stack
里坐落 PlatformView
之上会怎么?
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment(-0.6, -0.6),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment(-0.8, -0.8),
child: new Text(
"RE",
style: TextStyle(fontSize: 50, color: Colors.red),
),
),
Align(
alignment: Alignment.center,
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
)
],
)
能够看到尽管 FlutterImageView
没了,第二个赤色的 RE
也回到了默许的 Surface上,所以这便是 Hybrid Composition 混合原生控件的最基础设计理念:
-
直接把原生控件增加到
FlutterView
之上; - 原生和 Flutter 控件混合堆叠时,用新的
FlutterImageView
来完结层级掩盖; - 假如没有交集就不需求新的
FlutterImageView
;
关于 FlutterImageView
后面再打开,咱们持续这个比方,让两个 Flutter 的赤色 RE
都烘托到 PlatformView
的灰色的RE
上会是什么状况?
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment(0.6, 0),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment(0.6, 0),
child: new Text(
"RE",
style: TextStyle(fontSize: 50, color: Colors.red),
),
),
Align(
alignment: Alignment.center,
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
)
],
)
如上图所示,能够看到两个赤色的 Flutter RE
控件同享了一个 FlutterImageView
,这里能够得到一个新的定论:**和 PlatformView
有交集的同层级 Flutter 控件会同享同一个 FlutterImageView
。 **
咱们持续调整示例,如下代码咱们新增多一个 PlatformView
的灰色 RE
控件,然后调整方位,可是 Flutter 控件都在一个层级上,运转之后能够看到,只要 Flutter 控件都在同一个层级,就同享同一个 FlutterImageView
。
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment(-0.2, 0),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment(0.2, 0),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment(0, -0.1),
child: new Text(
"RE",
style: TextStyle(fontSize: 50, color: Colors.red),
),
),
Align(
alignment: Alignment(0, 0.2),
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
)
],
)
可是假如不在一个层级呢?咱们调整两个灰色 RE
的方位,让 PlatformView
的灰色 RE
和 Flutter 的赤色 RE
替换呈现。
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment(-0.2, 0),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment(0, -0.1),
child: new Text(
"RE",
style: TextStyle(fontSize: 50, color: Colors.red),
),
),
Align(
alignment: Alignment(0.2, 0),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment(0, 0.2),
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
)
],
)
能够看到,两个赤色的 Flutter RE
控件都独自被烘托都一个 FlutterImageView
上,所以咱们有新的定论:和 PlatformView
有交集的 Flutter 控件假如在不同层级,就需求不同的 FlutterImageView
来承载。
所以一般在运用 PlatformView
的场景上,不主张有过多的层级堆叠或许过于杂乱的 UI 场景。
接着咱们持续测验,还记得前面说过 Virtual Display 上关于接触作业的问题,所以此刻咱们直接给 PlatformView
的 灰色 RE
在原生层增加点击作业弹出 Toast 测验。
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment(-0.7, 0),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment(0.8, 0),
child: new Text(
"RE",
style: TextStyle(fontSize: 50, color: Colors.red),
),
),
Align(
alignment: Alignment.center,
child: Container(
color: Colors.amber,
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
),
),
],
)
能够看到运转后点击能够正常弹出 Toast ,所以关于 PlatformView
来说自身的点击和接触是能够正常保存,然后咱们调整下赤色大 RE
和灰色 RE
让他们发生交集,一起给赤色的大 RE
也增加点击作业,弹出 SnackBar
。
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment(-0.3, 0),
child: SizedBox(
height: 100,
width: 100,
child: NativeView(),
),
),
Align(
alignment: Alignment(0.8, 0),
child: new Text(
"RE",
style: TextStyle(fontSize: 50, color: Colors.red),
),
),
Align(
alignment: Alignment.center,
child: InkWell(
onTap: () {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: new Text("Re Click")));
},
child: Container(
color: Colors.amber,
child: new Text(
"RE",
style: TextStyle(fontSize: 100, color: Colors.red),
),
),
),
),
],
)
运转之后能够看到,点击没有被掩盖的灰色部分,仍是能够弹出 Toast ,点击赤色 RE
和灰色 RE
的交集处,能够正常弹出 SnackBar
。
所以能够看到 Hybrid Composition 上这种完结,能更原汁原味地保流下原生控件的作业和特性,由于从原生 视点,它便是原生层面的物理堆叠。
现在咱们应该大致关于 Hybrid Composition 有了必定理解,那回到前面那个一开始 Layout InSpector 黑屏 ,后来又能烘托出界面的原因,这就和首次增加 Hybrid Composition 时多出来的 FlutterImageView
有关系。
如下图所示,能够看到此刻原生的灰色 RE
和 Flutter 的赤色 RE
是没有交集的,为什么会多出来一个 FlutterImageView
呢?
这就需求说到 flutterView.convertToImageView()
这个方法。
在 Flutter 烘托 Hybrid Composition 的 PlatformView
时,会有一个 flutterView.convertToImageView()
的操作,这个操作是:把默许的 FlutterSurfaceView
烘托切换到 FlutterImageView
上 ,所以此刻会有一个 新增的 FlutterImageView
呈现在 FlutterSurfaceView
之上。
为什么需求
FlutterImageView
?那就要先理解下FlutterImageView
是怎么作业的,由于在前面咱们说过,和PlatformView
有交集的时分 Flutter 的控件也会被烘托到FlutterImageView
上。
FlutterImageView
自身是一个原生的 Android View 控件,它的内部有几个关键对象:
-
imageReader
:供给一个 surface ,而且能够直接访问到 surface 里的图画数据; -
flutterRenderer
: 外部传入的 Flutter 烘托类,这里用于切换/供给 Flutter Engine 里的烘托所需 surface ; -
currentImage
: 从imageReader
里提取出来的Image
画面; -
currentBitmap
:将Image
转为Bitmap
,用于onDraw
时制作;
所以简略地说 FlutterImageView
作业机制便是:经过 imageReader
供给 surface 给 Engine 烘托,然后把 imageReader
里的画面提取出来,烘托到 FlutterImageView
的 onDraw
上。
所以回归到前面的 flutterView.convertToImageView()
,在 Flutter 烘托 Hybrid Composition 的 PlatformView
时,会先把自己也变成了一个 FlutterImageView
,然后进入新的烘托流程:
- Flutter 在
onEndFrame
时,也便是每帧结束时,会判断当时界面是否还有PlatformView
,假如没有就会切换会默许的FlutterSurfaceView
; - 假如还存在
PlatformView
,就会调用acquireLatestImage
去获取当时imageReader
里的画面,得到新的currentBitmap
,然后触发invalidate
。 -
invalidate
会导致FlutterSurfaceView
履行onDraw
,然后把currentBitmap
里的内容制作出来。
所以咱们搞清楚了 FlutterImageView
的作用,也搞清楚了为什么有了 Hybrid Composition 的 PlatformView
之后,在 Android Studio 的 Layout Inspector 里能够看到 Flutter 控件的原因:
由于有 Hybrid Composition 之后,
FlutterSurfaceView
变成了FlutterImageView
,而FlutterImageView
制作是经过onDraw
,所以能够在 Layout Inspector 里呈现。
那为什么会有把 FlutterSurfaceView
变成了 FlutterImageView
这样的操作?原因其实是为了更好的动画同步和烘托作用。
由于前面说过,Hybrid Composition 是直接把增加到 FlutterView
上面,所以走的仍是原生的烘托流程和时机,而这时分经过把 FlutterSurfaceView
变成了 FlutterImageView
,也便是把 Flutter 控件烘托也同步到原生的 OnDraw
上,这样关于画面同步会更好。
那有人就要说了,我就不喜爱 FlutterImageView
的完结,有没有方法不在运用 Hybrid Composition 时把 FlutterSurfaceView
变成了 FlutterImageView
呢?
有的,官方在 PlatformViewsService
内供给了对应的设置支撑:
PlatformViewsService.synchronizeToNativeViewHierarchy(false);
在设置为 false 之后,能够看到只要 Hybrid Composition 的 PlatformView
的内容才能在 Layout Inspector 上看到,而 FlutterSurfaceView
看起来便是黑色空白。
问题
那 Hybrid Composition 便是完美吗? 肯定不是,事实上 Hybrid Composition 也有许多小问题,其间就比方功能问题。
例如在不运用 Hybrid Composition 的状况下,Flutter App 中 UI 是在特定的光栅线程运转,所以 Flutter 上 App 自身的主线程很少受到堵塞。
可是在 Hybrid Composition 下,Flutter UI 会由渠道的 onDraw
制作,这或许会导致必定程度上需求消耗渠道功能和占用通讯的开支。
例如在 Android 10 之前, Hybrid Composition 需求将内存中的每个 Flutter 制作的帧数据仿制到主内存,之后再从 GPU 烘托仿制回来 ,所以也会导致 Hybrid Composition 在 Android 10 之前的功能表现更差,例如在滚动列表里每个 Item 嵌套一个 Hybrid Composition 的 PlatformView
。
具体体现在 ImageReader 创建时,大于 29 的能够运用
HardwareBuffer
,而HardwareBuffer
允许在不同的应用程序进程之间同享缓冲区,经过HardwareBuffers
能够映射各种硬件体系的可访问 memory,例如 GPU。
所以假如当 Flutter 呈现动画卡顿时,或许你就应该考虑运用 Virtual Display 或许禁止 FlutterSurfaceView
变成了 FlutterImageView
。
事实上 Virtual Display 的功能也欠好,由于它的每个像素都需求经过额定的中心图形缓冲区。
未来变化
在现在 master 的 #31198 这个合并上,提出了新的完结方法用于替代现有的 Virtual Display 。
这个还未发布到正式本的调整上, Hybrid Composition 根本没有变化,首要是调整了一些命名,首要逻辑仍是在于 createForTextureLayer
,现在还无法确保它后续的发展,现在还有 一部分进度在 #97628 ,所以先简略介绍下它的状况。
在这个新的完结上,Virtual Display 的逻辑变成了 PlatformViewWrapper
, PlatformViewWrapper
自身是一个 FrameLayout
,同样是 flutterView.addView();
,根本逻辑和 Hybrid Composition 很像,只不过现在增加的是 PlatformViewWrapper
。
在这里 Virtual Display 没有了,本来 Virtual Display 创建的 Surface 被设置到 PlatformViewWrapper
里边。
简略介绍下:在 PlatformViewWrapper
里,会经过 surface.lockHardwareCanvas();
获取到当时 Surface
的 Canvas
,而且经过 draw(surfaceCanvas)
传递给了 child
。
所以 child
的 UI 就被制作到传入的 Surface
上,而 Flutter Engine 依据 Surface
的 id 又能够获取到对应的数据,经过一个不可视的 PlatformViewWrapper
完结了制作切换而无需运用 VirtualDisplay
。
当然,现在在测验中接收到的反应里有还不如曾经的功能好,所以后续会怎么调整仍是需求看测验结果。
PS ,假如这个修正正式发布,或许 Flutter 的 Android miniSDK 版别就需求到 23 起步了。由于
lockHardwareCanvas()
需求 23 起,而不必兼容更低渠道的原因是lockCanvas()
归于 CPU copy ,功能上会慢许多