BindingBase class Null safety
Base class for mixins that provide singleton services.
The Flutter engine (dart:ui) exposes some low-level services, but these are typically not suitable for direct use, for example because they only provide a single callback which an application may wish to multiplex to allow multiple listeners.
Bindings provide the glue between these low-level APIs and the higher-level framework APIs. They bind the two together, whence the name.
Implementing a binding mixin
A library would typically create a new binding mixin to expose a feature in dart:ui. This is rare in general, but it is something that an alternative framework would do, e.g. if a framework were to replace the widgets library with an alternative API but still wished to leverage the services and foundation libraries.
To create a binding mixin, declare a mixin on
the BindingBase class
and whatever other bindings the concrete binding must implement for
this binding mixin to be useful.
The mixin is guaranteed to only be constructed once in the lifetime of the app; this is handled by initInstances.
A binding mixin must at a minimum implement the following features:
- The initInstances method, which must call
super.initInstances
and set an_instance
static field tothis
. - An
instance
static getter, which must return that field using checkInstance.
In addition, it should implement whatever singleton features the library needs.
As a general rule, the less can be placed in the binding, the better. Prefer having APIs that takes objects rather than having them refer to global singletons. Bindings are best limited to exposing features that literally only exist once, for example, the APIs in dart:ui.
BarBinding
.
mixin FooBinding on BindingBase, BarBinding {
@override
void initInstances() {
super.initInstances();
_instance = this;
// ...binding initialization...
}
static FooBinding get instance => BindingBase.checkInstance(_instance);
static FooBinding? _instance;
// ...binding features...
}
Implementing a binding class
The top-most layer used to write the application (e.g. the Flutter widgets library) will have a concrete class that inherits from BindingBase and uses all the various BindingBase mixins (such as ServicesBinding). The widgets library in Flutter introduces a binding called WidgetsFlutterBinding.
A binding class should mix in the relevant bindings from each
layer that it wishes to expose, and should have an
ensureInitialized
method that constructs the class if that
layer's mixin's _instance
field is null. This allows the binding
to be overriden by developers who have more specific needs, while
still allowing other code to call ensureInitialized
when a binding
is needed.
ensureInitialized
method's
return type is the library's binding mixin, rather than the concrete
class.
class FooLibraryBinding extends BindingBase with BarBinding, FooBinding {
static FooBinding ensureInitialized() {
if (FooBinding._instance == null) {
FooLibraryBinding();
}
return FooBinding.instance;
}
}
Constructors
- BindingBase()
- Default abstract constructor for bindings.
Properties
- hashCode → int
-
The hash code for this object.
read-onlyinherited
- locked → bool
-
Whether lockEvents is currently locking events.
protected">@protectedread-only
- platformDispatcher → PlatformDispatcher
-
The ui.PlatformDispatcher to which this binding is bound.
read-only
- runtimeType → Type
-
A representation of the runtime type of the object.
read-onlyinherited
- window → SingletonFlutterWindow
-
The main window to which this binding is bound.
read-only
Methods
-
initInstances(
) → void -
The initialization method. Subclasses override this method to hook into
the platform and otherwise configure their services. Subclasses must call
"super.initInstances()".
mustCallSuper">@mustCallSuperprotected">@protected
-
initServiceExtensions(
) → void -
Called when the binding is initialized, to register service
extensions.
mustCallSuper">@mustCallSuperprotected">@protected
-
lockEvents(
Future< void> callback()) → Future<void> -
Locks the dispatching of asynchronous events and callbacks until the
callback's future completes.
protected">@protected
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a non-existent method or property is accessed.
inherited
-
performReassemble(
) → Future< void> -
This method is called by reassembleApplication to actually cause the
application to reassemble, e.g. after a hot reload.
mustCallSuper">@mustCallSuperprotected">@protected
-
postEvent(
String eventKind, Map< String, dynamic> eventData) → void -
All events dispatched by a BindingBase use this method instead of
calling developer.postEvent directly so that tests for BindingBase
can track which events were dispatched by overriding this method.
protected">@protected
-
reassembleApplication(
) → Future< void> - Cause the entire application to redraw, e.g. after a hot reload.
-
registerBoolServiceExtension(
{required String name, required AsyncValueGetter< bool> getter, required AsyncValueSetter<bool> setter}) → void -
Registers a service extension method with the given name (full
name "ext.flutter.name"), which takes a single argument
"enabled" which can have the value "true" or the value "false"
or can be omitted to read the current value. (Any value other
than "true" is considered equivalent to "false". Other arguments
are ignored.)
protected">@protected
-
registerNumericServiceExtension(
{required String name, required AsyncValueGetter< double> getter, required AsyncValueSetter<double> setter}) → void -
Registers a service extension method with the given name (full
name "ext.flutter.name"), which takes a single argument with the
same name as the method which, if present, must have a value
that can be parsed by double.parse, and can be omitted to read
the current value. (Other arguments are ignored.)
protected">@protected
-
registerServiceExtension(
{required String name, required ServiceExtensionCallback callback}) → void -
Registers a service extension method with the given name (full name
"ext.flutter.name").
protected">@protected
-
registerSignalServiceExtension(
{required String name, required AsyncCallback callback}) → void -
Registers a service extension method with the given name (full
name "ext.flutter.name"), which takes no arguments and returns
no value.
protected">@protected
-
registerStringServiceExtension(
{required String name, required AsyncValueGetter< String> getter, required AsyncValueSetter<String> setter}) → void -
Registers a service extension method with the given name (full name
"ext.flutter.name"), which optionally takes a single argument with the
name "value". If the argument is omitted, the value is to be read,
otherwise it is to be set. Returns the current value.
protected">@protected
-
toString(
) → String -
A string representation of this object.
override
-
unlocked(
) → void -
Called by lockEvents when events get unlocked.
mustCallSuper">@mustCallSuperprotected">@protected
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Properties
- debugReassembleConfig ↔ DebugReassembleConfig?
-
Additional configuration used by the framework during hot reload.
read / write
Static Methods
-
checkInstance<
T extends BindingBase> (T? instance) → T -
A method that shows a useful error message if the given binding
instance is not initialized.
protected">@protected
-
debugBindingType(
) → Type? - In debug builds, the type of the current binding, if any, or else null.