前言
Flutter中所有的运转都是在各种Binding中调度的,也正是这些绑定器的存在彻底解耦了Widget 、 Element 、RenderObject 对 Platform端的依赖,阅读此文需要有一定的Flutter基础,如:Flutter的绘制流程,Flutter与Platform通信原理,Flutter 三棵树各自的职责
WidgetsFlutterBinding
WidgetsFlutterBinding是一个单例存,它继承了GestureBinding, SchedulerBinding, ServicesBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding,负责Widget和Engine之间的粘合工作
class WidgetsFlutterBinding extends BindingBase with GestureBinding, SchedulerBinding, ServicesBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
static WidgetsBinding ensureInitialized() {
if (WidgetsBinding.instance == null)
WidgetsFlutterBinding();
return WidgetsBinding.instance!;
}
}
所有的Binding都是为上层的Widget,Element,RenderObject提供调用的,如下图所示:
事件调度绑定器 — GestureBinding
GestureBinding是对Flutter中的事件分发管理,具体可以参考浅谈Flutter核心机制之— 事件分发
void initInstances() {
super.initInstances();
_instance = this;
window.OnPointerDataPacket= _handlePointerDataPacket;
}
void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) {
...
for (final HitTestEntry entry in hitTestResult.path) {
try {
entry.target.handleEvent(event.transformed(entry.transform), entry);
} catch (exception, stack) {
}
}
}
@override // from HitTestTarget
void handleEvent(PointerEvent event, HitTestEntry entry) {
pointerRouter.route(event);
if (event is PointerDownEvent) {
gestureArena.close(event.pointer);
} else if (event is PointerUpEvent) {
gestureArena.sweep(event.pointer);
} else if (event is PointerSignalEvent) {
pointerSignalResolver.resolve(event);
}
}
任务调度绑定器 — SchedulerBinding
SchedulerBinding是任务调度器,它负责处理对各种类型任务调度的时机, 执行 UI构建前/UI构建后的一些任务,除此之外还可以对任务进行优先级排序
void handleBeginFrame(Duration? rawTimeStamp) {
Timeline.startSync('Frame', arguments: timelineArgumentsIndicatingLandmarkEvent);
_firstRawTimeStampInEpoch ??= rawTimeStamp;
_currentFrameTimeStamp = _adjustForEpoch(rawTimeStamp ?? _lastRawTimeStamp);
if (rawTimeStamp != null)
_lastRawTimeStamp = rawTimeStamp;
_hasScheduledFrame = false;
try {
// TRANSIENT FRAME CALLBACKS
Timeline.startSync('Animate', arguments: timelineArgumentsIndicatingLandmarkEvent);
_schedulerPhase = SchedulerPhase.transientCallbacks;
final Map
void handleDrawFrame() {
assert(_schedulerPhase == SchedulerPhase.midFrameMicrotasks);
Timeline.finishSync(); // end the "Animate" phase
try {
// PERSISTENT FRAME CALLBACKS
_schedulerPhase = SchedulerPhase.persistentCallbacks;
for (final FrameCallback callback in _persistentCallbacks)
_invokeFrameCallback(callback, _currentFrameTimeStamp!);
// POST-FRAME CALLBACKS
_schedulerPhase = SchedulerPhase.postFrameCallbacks;
final List localPostFrameCallbacks =
List.from(_postFrameCallbacks);
_postFrameCallbacks.clear();
for (final FrameCallback callback in localPostFrameCallbacks)
_invokeFrameCallback(callback, _currentFrameTimeStamp!);
} finally {
_schedulerPhase = SchedulerPhase.idle;
Timeline.finishSync(); // end the Frame
assert(() {
if (debugPrintEndFrameBanner)
debugPrint('▀' * _debugBanner!.length);
_debugBanner = null;
return true;
}());
_currentFrameTimeStamp = null;
}
}
void addTimingsCallback(TimingsCallback callback) {
_timingsCallbacks.add(callback);
if (_timingsCallbacks.length == 1) {
assert(window.OnReportTimings== null);
window.OnReportTimings= _executeTimingsCallbacks;
}
assert(window.OnReportTimings== _executeTimingsCallbacks);
}
Future
int scheduleFrameCallback(FrameCallback callback, { bool rescheduling = false }) {
scheduleFrame();
_nextFrameCallbackId += 1;
_transientCallbacks[_nextFrameCallbackId] = _FrameCallbackEntry(callback, rescheduling: rescheduling);
return _nextFrameCallbackId;
}
void addPersistentFrameCallback(FrameCallback callback) {
_persistentCallbacks.add(callback);
}
void addPostFrameCallback(FrameCallback callback) {
_postFrameCallbacks.add(callback);
}
void scheduleFrame() {
if (_hasScheduledFrame || !framesEnabled)
return;
ensureFrameCallbacksRegistered();
window.scheduleFrame();
_hasScheduledFrame = true;
}
服务绑定器 — ServicesBinding
ServicesBinding注册管理了一些平台服务,如消息通信信使_defaultBinaryMessenger,平台的各种生命周期等等
void initInstances() {
super.initInstances();
_instance = this;
//与platform通信的信使
_defaultBinaryMessenger = createBinaryMessenger();
//状态恢复回调
_restoratiOnManager= createRestorationManager();
window.OnPlatformMessage= defaultBinaryMessenger.handlePlatformMessage;
initLicenses();
//系统消息处理,如内存低 。。
SystemChannels.system.setMessageHandler((dynamic message) => handleSystemMessage(message as Object));
//生命周期
SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
readInitialLifecycleStateFromNativeWindow();
}
//发送二进制消息发给platform
Future
//该方法被子类重写了
@protected
@mustCallSuper
Future
static AppLifecycleState? _parseAppLifecycleMessage(String message) {
switch (message) {
case 'AppLifecycleState.paused':
return AppLifecycleState.paused;
case 'AppLifecycleState.resumed':
return AppLifecycleState.resumed;
case 'AppLifecycleState.inactive':
return AppLifecycleState.inactive;
case 'AppLifecycleState.detached':
return AppLifecycleState.detached;
}
return null;
}
@protected
RestorationManager createRestorationManager() {
return RestorationManager();
}
图像绑定器 — PaintingBinding
PaintingBinding比较简单,就是管理了Flutter图像缓存和创建图像编解码器,以及对GPU着色器程序预热
辅助服务绑定器 — SemanticsBinding
SemanticsBinding处理Platform上辅助服务事件
渲染绑定器 — RendererBinding
RendererBinding是一个核心组件,它里面管理了渲染管线PipelineOwner(管理RenderObject),以及注册platform显示相关的监听,如:亮度改变,字体缩放因子改变等等,它里面创建了第一个RenderObject ---- RenderView
void initInstances() {
super.initInstances();
_instance = this;
//渲染管线,管理需要刷新的RenderObject
_pipelineOwner = PipelineOwner(
onNeedVisualUpdate: ensureVisualUpdate,
onSemanticsOwnerCreated: _handleSemanticsOwnerCreated,
onSemanticsOwnerDisposed: _handleSemanticsOwnerDisposed,
);
window
..OnMetricsChanged= handleMetricsChanged
..OnTextScaleFactorChanged= handleTextScaleFactorChanged
..OnPlatformBrightnessChanged= handlePlatformBrightnessChanged
..OnSemanticsEnabledChanged= _handleSemanticsEnabledChanged
..OnSemanticsAction= _handleSemanticsAction;
//创建第一个 RenderObject ---- RenderView
initRenderView();
_handleSemanticsEnabledChanged();
assert(renderView != null);
//注册绘制流水线回调,可参考SchedulerBinding中第6条
addPersistentFrameCallback(_handlePersistentFrameCallback);
initMouseTracker();
if (kIsWeb) {
addPostFrameCallback(_handleWebFirstFrame);
}
}
绘制核心方法 drawFrame
@protected
void drawFrame() {
assert(renderView != null);
//刷新需要布局
pipelineOwner.flushLayout();
pipelineOwner.flushCompositingBits();
//刷新绘制
pipelineOwner.flushPaint();
if (sendFramesToEngine) {
//生成Scene发送到Engine
renderView.compositeFrame(); // this sends the bits to the GPU
pipelineOwner.flushSemantics(); // this also sends the semantics to the OS.
_firstFrameSent = true;
}
}
Widget绑定器 — WidgetsBinding
WidgetsBinding是Widget三棵树的入口,处理Widget, Element之间的一些业务,如:给Widget层注册生命周期的监听,亮度改变等等
void runApp(Widget app) {
WidgetsFlutterBinding.ensureInitialized()
..scheduleAttachRootWidget(app)
..scheduleWarmUpFrame();
}
void initInstances() {
super.initInstances();
_instance = this;
//管理Element标脏,回收
_buildOwner = BuildOwner();
buildOwner!.OnBuildScheduled= _handleBuildScheduled;
//语言,时区
window.OnLocaleChanged= handleLocaleChanged;
window.OnAccessibilityFeaturesChanged= handleAccessibilityFeaturesChanged;
SystemChannels.navigation.setMethodCallHandler(_handleNavigationInvocation);
FlutterErrorDetails.propertiesTransformers.add(transformDebugCreator);
}
void drawFrame() {
...
try {
if (renderViewElement != null)
// 对标脏的Element进行重建,从而生成新的三棵树
buildOwner!.buildScope(renderViewElement!);
//见RendererBinding#drawFrame
super.drawFrame();
//卸载不再使用的Element
buildOwner!.finalizeTree();
} finally {
}
}
总结
通过以上分析可以得知Flutter中各Binding组件之间的协同工作构建出Flutter UI交互系统,它们之间又相对独立的只负责一类职责这样很好的解耦了业务之间的耦合度