runWidget function
- Widget app
Inflate the given widget and bootstrap the widget tree.
Unlike runApp, this method does not define a FlutterView into which the
provided app
widget is rendered into. It is up to the caller to include at
least one View widget in the provided app
widget that will bootstrap a
render tree and define the FlutterView into which content is rendered.
RenderObjectWidgets without an ancestor View widget will result in an
exception. Apps that want to render into the default view without dealing
with view management should consider calling runApp instead.
MyApp
widget will be drawn:
runWidget(
View(
view: myFlutterView,
child: const MyApp(),
),
);
Calling runWidget again will detach the previous root widget and attach the given widget in its place. The new widget tree is compared against the previous widget tree and any differences are applied to the underlying render tree, similar to what happens when a StatefulWidget rebuilds after calling State.setState.
Initializes the binding using WidgetsFlutterBinding if necessary.
Application shutdown
This widget tree is not torn down when the application shuts down, because there is no way to predict when that will happen. For example, a user could physically remove power from their device, or the application could crash unexpectedly, or the malware on the device could forcibly terminate the process.
Applications are responsible for ensuring that they are well-behaved even in the face of a rapid unscheduled termination.
To listen for platform shutdown messages (and other lifecycle changes), consider the AppLifecycleListener API.
To artificially cause the entire widget tree to be disposed, consider calling runWidget with a ViewCollection that does not specify any ViewCollection.views.
Dismissing Flutter UI via platform native methods
An application may have both Flutter and non-Flutter UI in it. If the application calls non-Flutter methods to remove Flutter based UI such as platform native API to manipulate the platform native navigation stack, the framework does not know if the developer intends to eagerly free resources or not. The widget tree remains mounted and ready to render as soon as it is displayed again.
To release resources more eagerly, establish a platform channel
and use it to remove the View whose widget resources should be released
from the app
widget tree provided to runWidget.
See also:
- runApp, which bootstraps a widget tree and renders it into a default FlutterView.
- WidgetsBinding.attachRootWidget, which creates the root widget for the widget hierarchy.
- RenderObjectToWidgetAdapter.attachToRenderTree, which creates the root element for the element hierarchy.
- WidgetsBinding.handleBeginFrame, which pumps the widget pipeline to ensure the widget, element, and render trees are all built.
Implementation
// TODO(goderbauer): Update the paragraph below to include the Window widget once that exists.
/// Unlike [runApp], this method does not define a [FlutterView] into which the
/// provided `app` widget is rendered into. It is up to the caller to include at
/// least one [View] widget in the provided `app` widget that will bootstrap a
/// render tree and define the [FlutterView] into which content is rendered.
/// [RenderObjectWidget]s without an ancestor [View] widget will result in an
/// exception. Apps that want to render into the default view without dealing
/// with view management should consider calling [runApp] instead.
///
/// {@tool snippet}
/// The sample shows how to utilize [runWidget] to specify the [FlutterView]
/// into which the `MyApp` widget will be drawn:
///
/// ```dart
/// runWidget(
/// View(
/// view: myFlutterView,
/// child: const MyApp(),
/// ),
/// );
/// ```
/// {@end-tool}
///
/// Calling [runWidget] again will detach the previous root widget and attach
/// the given widget in its place. The new widget tree is compared against the
/// previous widget tree and any differences are applied to the underlying
/// render tree, similar to what happens when a [StatefulWidget] rebuilds after
/// calling [State.setState].
///
/// Initializes the binding using [WidgetsFlutterBinding] if necessary.
///
/// {@macro flutter.widgets.runApp.shutdown}
///
/// To artificially cause the entire widget tree to be disposed, consider
/// calling [runWidget] with a [ViewCollection] that does not specify any
/// [ViewCollection.views].
///
/// {@macro flutter.widgets.runApp.dismissal}
///
/// To release resources more eagerly, establish a [platform channel](https://flutter.dev/to/platform-channels)
/// and use it to remove the [View] whose widget resources should be released
/// from the `app` widget tree provided to [runWidget].
///
/// See also:
///
/// * [runApp], which bootstraps a widget tree and renders it into a default
/// [FlutterView].
/// * [WidgetsBinding.attachRootWidget], which creates the root widget for the
/// widget hierarchy.
/// * [RenderObjectToWidgetAdapter.attachToRenderTree], which creates the root
/// element for the element hierarchy.
/// * [WidgetsBinding.handleBeginFrame], which pumps the widget pipeline to
/// ensure the widget, element, and render trees are all built.
void runWidget(Widget app) {
final WidgetsBinding binding = WidgetsFlutterBinding.ensureInitialized();
_runWidget(app, binding, 'runWidget');
}