Flutter源码学习pt.1-4总结, WidgetsFlutterBinding的秘密
跨平台的秘密之一Binding
我们惊讶于Flutter的跨平台特性,一切皆Widget
,这些概念对Android开发者来说,都是新奇的,不易接受的,Android的四大组件,是非常经典设计模式,但在UI构建层面,xml+code
, 以及 View
和 Pointer
的耦合,确实相当落后的命令式
的写法。真正理解这个UI层面的差异,以及跨平台的的方案,我们最好是通过源码来看高层的设计
,如何做到组合式的UI以及一切皆Widget的原理。
Binding
在其中是非常重要的存在. 我们通过一段必须使用的代码了解他。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp();
}
这是我们启动展示我们自己Widget
之前,必须调用的,它做了运行我们自己Widget之前的环境准备工作。我们很少会主动看这个写法,因为他像Android开发中的Application
, 环境的准备过程经常会被忽略。我们细看一下环境的准备工作,上代码。
class WidgetsFlutterBinding extends BindingBase with GestureBinding, SchedulerBinding, ServicesBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
static WidgetsBinding ensureInitialized() {
if (WidgetsBinding._instance == null) {
WidgetsFlutterBinding();
}
return WidgetsBinding.instance;
}
}
我们看到WidgetsFlutterBinding
实现了BindingBase
并聚合了GestureBinding(点击), SchedulerBinding(帧), ServicesBinding(平台服务), PaintingBinding(图像绘制), SemanticsBinding(语义), RendererBinding(渲染), WidgetsBinding(UI)
,方法虽然返回WidgetsBinding.instance
, 但 初始化的工作,却是WidgetsFlutterBinding
, 也就是父类BindingBase
的构造函数,上主流程代码。
BindingBase() {
if (!kReleaseMode) {
FlutterTimeline.startSync('Framework initialization');
}
// 初始化所有Binding
initInstances();
// 初始化所有系统级服务
initServiceExtensions();
if (!kReleaseMode) {
FlutterTimeline.finishSync();
}
}
/// GestureBinding
@override
void initInstances() {
super.initInstances();
_instance = this;
platformDispatcher.onPointerDataPacket = _handlePointerDataPacket;
}
static GestureBinding get instance => BindingBase.checkInstance(_instance);
static GestureBinding? _instance;
上述流程清晰的展示了,Binding是单例
的,当我们调用完成WidgetsFlutterBinding
, 所有的系统组件都已完成初始化。我对mixin GestureBinding on BindingBase
非常感兴趣,我们之后再探究他的实现原理和用法。我们回头看前面几节分析的SchedulerBinding
的初始化
和engine(引擎)
如何连接。
mixin SchedulerBinding on BindingBase {
@override
void initInstances() {
super.initInstances();
_instance = this;
if (!kReleaseMode) {
addTimingsCallback((List<FrameTiming> timings) {
timings.forEach(_profileFramePostEvent);
});
}
}
}
我们会惊讶的发现SchedulerBinding
初始化时并不和系统有任何交互,它像是一个中间层,负责调度,并不关心和系统的交互。但GestureBinding
初始化时,粘合了平台系统Pointer
到Flutter
。 这也展示了粘合的另一个作用,和平台粘合。
mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, HitTestTarget {
@override
void initInstances() {
super.initInstances();
_instance = this;
platformDispatcher.onPointerDataPacket = _handlePointerDataPacket;
}
}
总结
Binding
有很多, 当前不一一介绍,当使用到的时候,我们再进行分析。概况的来说,Binding是系统和Flutter,Flutter不同功能之间的粘合剂,聚合了运行环境,是运行我们自己Widget的基础。下一篇,预计分析绘制流程
以及调试过程
。
转载自:https://juejin.cn/post/7348646483384320050