SchedulerBinding and WidgetsBinding in Flutter
Flutter uses various bindings to connect different parts of the framework. SchedulerBinding and WidgetsBinding are two such bindings that are widely used in Flutter. Let’s discuss these two bindings and understand the difference between them.
SchedulerBinding
In Flutter, SchedulerBinding is responsible for scheduling and executing frame-related callbacks. It has 3 main types of callback:
1. Transient Callbacks
- Triggered by Window.onBeginFrame
- Used for synchronizing app activities with system display
- Used in Ticker and AnimationController
class AnimationExample extends StatefulWidget {
@override
_AnimationExampleState createState() => _AnimationExampleState();
}
class _AnimationExampleState extends State<AnimationExample> with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat();
}
}
2. Persistent Callbacks
- Triggered by Window.onDrawFrame
- It’s used to update the display after the transient callback has finished.
class RenderExample extends StatefulWidget {
@override
_RenderExampleState createState() => _RenderExampleState();
}
class _RenderExampleState extends State<RenderExample> {
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPersistentFrameCallback((_) {
// Called after each frame
print("Frame rendered");
});
}
}
3. Post-Frame Callbacks
- Triggered after Window.onDrawFrame completes
- It is executed after the Persistent callback finishes
- Used to run non-rendering tasks after each frame finishes loading
class PostFrameExample extends StatefulWidget {
@override
_PostFrameExampleState createState() => _PostFrameExampleState();
}
class _PostFrameExampleState extends State<PostFrameExample> {
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
// Show dialog after first frame
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Welcome!'),
),
);
});
}
}
WidgetsBinding
WidgetBinding is used for connection between the widgets layer and the Flutter engine. It does the following:
- Manages widget state
- Triggers widget building and layout
- Handles widget’s lifecycle
- Manages the Element tree rooted at rootElement
class LifecycleExample extends StatefulWidget {
@override
_LifecycleExampleState createState() => _LifecycleExampleState();
}
class _LifecycleExampleState extends State<LifecycleExample> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
print("App resumed");
break;
case AppLifecycleState.inactive:
print("App inactive");
break;
case AppLifecycleState.paused:
print("App paused");
break;
case AppLifecycleState.detached:
print("App detached");
break;
}
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
SchedulerBinding vs WidgetsBinding
1. Functionality Scope
- SchedulerBinding focuses purely on frame scheduling and execution
- WidgetsBinding provides comprehensive widget-related functionality and includes SchedulerBinding functionality
2. Inheritance
- WidgetBindings inherits from SchedulerBinding
- When you use WidgetBindings.instance, you are essentially using SchedulerBinding.instance
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
print("WidgetsBinding callback");
});
SchedulerBinding.instance.addPostFrameCallback((_) {
print("SchedulerBinding callback");
});
}
As you can see above, you can use either of these bindings. The calls will execute in the order they were added. Since WidgetsBinding was added earlier, it will print first.
Best Practise
While you can use either of these bindings, WidgetsBinding is usually recommended for the following reasons:
- Semantically, it’s more correct for use with Widgets
- It indicates that you are working with Widgets
- It’s the standard approach used in Flutter codebases.
You can read more about SchedulerBinding and WidgetBinding in the official Flutter documentation. You can read our article on General Architectural and Design Patterns in Flutter next.