Skip to main content

RestorationManager

Struct RestorationManager 

Source
pub struct RestorationManager { /* private fields */ }
Expand description

Manages the restoration data in the framework and synchronizes it with the host.

Restoration data can be serialized out and - at a later point in time - be used to restore the application to the previous state described by the serialized data. Mobile operating systems use the concept of state restoration to provide the illusion that apps continue to run in the background forever: after an app has been backgrounded, the user can always return to it and find it in the same state. In practice, the operating system may, however, terminate the app to free resources for other apps running in the foreground. Before that happens, the app gets a chance to serialize out its restoration data. When the user navigates back to the backgrounded app, it is restarted and the serialized restoration data is provided to it again. Ideally, the app will use that data to restore itself to the same state it was in when the user backgrounded the app.

Restoration data is organized in a tree of RestorationBuckets which is rooted in the root_bucket. All information that the application needs to restore its current state must be stored in a bucket in this hierarchy. To store data in the hierarchy, entities must claim ownership of a child bucket from a parent bucket (which may be the root bucket provided by this RestorationManager). The owner of a bucket may store arbitrary RestorationData in the bucket. The values are stored in the bucket under a given restoration ID as key. A restoration ID is a string that must be unique within a given bucket. To access the stored value again during state restoration, the same restoration ID must be provided again. The owner of the bucket may also make the bucket available to other entities so that they can claim child buckets from it for their own restoration needs. Within a bucket, child buckets are also identified by unique restoration IDs. The restoration ID must be provided when claiming a child bucket.

When restoration data is provided to the RestorationManager (e.g. after the application relaunched when foregrounded again), the bucket hierarchy with all the data stored in it is restored. Entities can retrieve the data again by using the same restoration IDs that they originally used to store the data.

In addition to providing restoration data when the app is launched, restoration data may also be provided to a running app to restore it to a previous state (e.g. when the user hits the back/forward button in the web browser). When this happens, the RestorationManager notifies its listeners (added via add_listener) that a new root bucket is available. In response to the notification, listeners must stop using the old bucket and restore their state from the information in the new root bucket.

Some platforms restrict the size of the restoration data. Therefore, the data stored in the buckets should be as small as possible while still allowing the app to restore its current state from it. Data that can be retrieved from other services (e.g. a database or a web server) should not be included in the restoration data. Instead, a small identifier (e.g. a UUID, database record number, or resource locator) should be stored that can be used to retrieve the data again from its original source during state restoration.

The RestorationManager sends a copy of the bucket hierarchy over to the host at the end of a frame in which the data in the hierarchy or its shape has changed. The host caches the data until the operating system needs it. The application is responsible for keeping the data in the bucket always up-to-date to reflect its current state.

§Discussion

Due to the threading model of the platforms Flutter runs on, restoration data must be stored in the buckets proactively as described above. When the operating system asks for the restoration data, it will do so on the platform thread expecting a synchronous response. To avoid the risk of deadlocks, the platform thread cannot block and call into the thread running the application to retrieve the restoration data. For this reason, the RestorationManager always sends the latest copy of the restoration data over to the host whenever it changes. That way, the restoration data is always ready to go on the platform thread when the operating system needs it.

Dart’s ServicesBinding.restorationManager is instance, the App’s singleton.

See also:

Implementations§

Source§

impl RestorationManager

Source

pub fn instance(app: &mut App) -> Handle<RestorationManager>

The application’s restoration manager.

Dart’s ServicesBinding.instance.restorationManager.

Source

pub fn root_bucket( self: Handle<Self>, app: &mut App, ) -> Option<Handle<RestorationBucket>>

The root of the RestorationBucket hierarchy containing the restoration data.

Child buckets can be claimed from this bucket via RestorationBucket::claim_child. If the RestorationManager has been asked to restore the application to a previous state, these buckets will contain the previously stored data. Otherwise the root bucket (and all children claimed from it) will be empty.

The RestorationManager informs its listeners when the value returned by this getter changes. This happens when new restoration data has been provided to the RestorationManager to restore the application to a different state. In response to the notification, listeners must stop using the old root bucket and obtain the new one via this getter (it will have been updated to return the new bucket just before the listeners are notified).

The restoration data describing the current bucket hierarchy is retrieved from the host the first time the root bucket is accessed via this getter.

Returns None if state restoration is currently turned off.

Source

pub fn is_replacing(self: Handle<Self>, app: &App) -> bool

Returns true for the frame after the root bucket has been replaced with a new non-null bucket.

When true, entities should forget their current state and restore their state according to the information in the new root bucket.

The RestorationManager informs its listeners when this flag changes from false to true.

Source

pub fn handle_restoration_update_from_engine( self: Handle<Self>, app: &mut App, enabled: bool, data: Option<RestorationMap>, )

Parses the restoration information obtained from the host.

The enabled parameter indicates whether the host wants to receive restoration data. When enabled is false, state restoration is turned off and the root bucket is set to None. When enabled is true, the provided restoration data becomes the new root bucket. If data is None, an empty root bucket is instantiated.

A host may call this method at any time to inject restoration data (obtained e.g. from send_to_engine) into the RestorationManager, which is what Flutter’s push message on SystemChannels.restoration does. When the method is called before the root bucket is accessed, root_bucket answers without asking the host.

Source

pub fn send_to_engine( self: Handle<Self>, app: &mut App, encoded_data: RestorationMap, )

Sends the provided restoration data to the host.

The encoded_data describes the entire bucket hierarchy that makes up the current restoration data.

Source

pub fn schedule_serialization_for( self: Handle<Self>, app: &mut App, bucket: Handle<RestorationBucket>, )

Called by a RestorationBucket to request serialization for that bucket.

This method is called by a bucket in the hierarchy whenever the data in it or the shape of the hierarchy has changed.

Calling this is a no-op when the bucket is already scheduled for serialization.

Source

pub fn unschedule_serialization_for( self: Handle<Self>, app: &mut App, bucket: Handle<RestorationBucket>, )

Called by a RestorationBucket to unschedule a request for serialization.

This method is called by a bucket in the hierarchy whenever it no longer needs to be serialized (e.g. because the bucket got disposed).

It is safe to call this even when the bucket wasn’t scheduled for serialization before.

Source

pub fn flush_data(self: Handle<Self>, app: &mut App)

Called to manually flush the restoration data to the host.

A change in restoration data is usually accompanied by scheduling a frame (because the restoration data is modified inside a State::set_state call, because it is usually something that affects the interface). Restoration data is automatically flushed to the host at the end of a frame. As a result, it is uncommon to need to call this method directly. However, if restoration data is changed without triggering a frame, this method must be called to ensure that the updated restoration data is sent to the host in a timely manner. An example of such a use case is the scrollable, where the final scroll offset after a scroll activity finishes is determined between frames without scheduling a new frame.

Calling this method is a no-op if a frame is already scheduled. In that case, the restoration data will be flushed to the host at the end of that frame. If this method is called and no frame is scheduled, the current restoration data is directly sent to the host.

Source

pub fn dispose(self: Handle<Self>, app: &mut App)

Discards any resources used by the manager, and the root bucket with them.

Trait Implementations§

Source§

impl ChangeNotifier for RestorationManager

Source§

fn change_notifier_data(&self) -> &ChangeNotifierData

Source§

fn change_notifier_data_mut(&mut self) -> &mut ChangeNotifierData

Source§

fn will_add_listener(self: Handle<Self>, app: &mut App)

Runs before the listener is stored. Dart overrides of addListener that work before super.addListener go here.
Source§

fn did_remove_listener(self: Handle<Self>, app: &mut App)

Runs after the listener is removed. Dart overrides of removeListener that work after super.removeListener go here.
Source§

impl Default for RestorationManager

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ListenableObject for T
where T: ChangeNotifier,

Source§

fn add_listener(self: Handle<T>, app: &mut App, listener: Listener)

Register a closure to be called when the object notifies its listeners.
Source§

fn remove_listener(self: Handle<T>, app: &mut App, listener: &Listener)

Remove a previously registered closure from the list of closures that the object notifies.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>