abstractclassBindingBase{ /// 省略代码 /// However, multiple window support is not yet implemented, so currently this /// provides access to the one and only window. // TODO(gspencergoog): remove the preceding note once multi-window support is // active. // 唯一的window ui.SingletonFlutterWindow getwindow => ui.window; /// 每一个BindingBase类定义行为 都有一个 platformDispatcher 作为回调(handlers) ui.PlatformDispatcher get platformDispatcher => ui.PlatformDispatcher.instance; /// 初始化实例 void initInstances() { assert(!_debugInitialized); assert(() { _debugInitialized = true; returntrue; }()); } /// The current [WidgetsBinding], if one has been created. /// ensureInitialized方法返回的实例 /// If you need the binding to be constructed before calling [runApp], /// you can ensure a Widget binding has been constructed by calling the /// `WidgetsFlutterBinding.ensureInitialized()` function. static WidgetsBinding? get instance => _instance; static WidgetsBinding? _instance; /// 注册 service extensions 初始化之后调用 void initServiceExtensions() { ///省略代码 } }
/// The current [RendererBinding], if one has been created. static RendererBinding? get instance => _instance; static RendererBinding? _instance; ///省略代码 }
void ensureVisualUpdate() { switch (schedulerPhase) { case SchedulerPhase.idle: case SchedulerPhase.postFrameCallbacks: scheduleFrame(); return; case SchedulerPhase.transientCallbacks: case SchedulerPhase.midFrameMicrotasks: case SchedulerPhase.persistentCallbacks: return; } }
它主要是调用新的帧的调度管理。它会调用scheduleFrame方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void scheduleFrame() { if (_hasScheduledFrame || !framesEnabled) return; assert(() { if (debugPrintScheduleFrameStacks) debugPrintStack(label: 'scheduleFrame() called. Current phase is $schedulerPhase.'); returntrue; }()); ///给window设置回调 ensureFrameCallbacksRegistered(); ///调度更新 window.scheduleFrame(); _hasScheduledFrame = true; }
void scheduleWarmUpFrame() { if (_warmUpFrame || schedulerPhase != SchedulerPhase.idle) return; _warmUpFrame = true; Timeline.startSync('Warm-up frame'); finalbool hadScheduledFrame = _hasScheduledFrame; // We use timers here to ensure that microtasks flush in between. Timer.run(() { assert(_warmUpFrame); handleBeginFrame(null); }); Timer.run(() { assert(_warmUpFrame); handleDrawFrame(); // We call resetEpoch after this frame so that, in the hot reload case, // the very next frame pretends to have occurred immediately after this // warm-up frame. The warm-up frame's timestamp will typically be far in // the past (the time of the last real frame), so if we didn't reset the // epoch we would see a sudden jump from the old time in the warm-up frame // to the new time in the "real" frame. The biggest problem with this is // that implicit animations end up being triggered at the old time and // then skipping every frame and finishing in the new time. resetEpoch(); _warmUpFrame = false; if (hadScheduledFrame) scheduleFrame(); }); // Lock events so touch events etc don't insert themselves until the // scheduled frame has finished. lockEvents(() async { await endOfFrame; Timeline.finishSync(); }); }