Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | List of all members
io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager Interface Reference
Inheritance diagram for io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager:
io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager

Public Member Functions

abstract void setJNI (FlutterJNI flutterJNI)
 
abstract void setDeferredComponentChannel (DeferredComponentChannel channel)
 
abstract void installDeferredComponent (int loadingUnitId, String componentName)
 
abstract String getDeferredComponentInstallState (int loadingUnitId, String componentName)
 
abstract void loadAssets (int loadingUnitId, String componentName)
 
abstract void loadDartLibrary (int loadingUnitId, String componentName)
 
abstract boolean uninstallDeferredComponent (int loadingUnitId, String componentName)
 
abstract void destroy ()
 

Detailed Description

Basic interface that handles downloading and loading of deferred components.

Flutter deferred component support is still in early developer preview and should not be used in production apps yet.

The Flutter default implementation is PlayStoreDeferredComponentManager.

DeferredComponentManager handles the embedder/Android level tasks of downloading, installing, and loading Dart deferred libraries. A typical code-flow begins with a Dart call to loadLibrary() on deferred imported library. See https://dart.dev/guides/language/language-tour#deferred-loading This call retrieves a unique identifier called the loading unit id, which is assigned by gen_snapshot during compilation. The loading unit id is passed down through the engine and invokes installDeferredComponent. Once the component is downloaded, loadAssets and loadDartLibrary should be invoked. loadDartLibrary should find shared library .so files for the engine to open and pass the .so path to FlutterJNI.loadDartDeferredLibrary. loadAssets should typically ensure the new assets are available to the engine's asset manager by passing an updated Android AssetManager to the engine via FlutterJNI.updateAssetManager.

The loadAssets and loadDartLibrary methods are separated out because they may also be called manually via platform channel messages. A full installDeferredComponent implementation should call these two methods as needed.

A deferred component is uniquely identified by a component name as defined in bundle_config.yaml. Each component may contain one or more loading units, uniquely identified by the loading unit ID and assets.

Definition at line 38 of file DeferredComponentManager.java.

Member Function Documentation

◆ destroy()

abstract void io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.destroy ( )
abstract

Cleans up and releases resources. This object is no longer usable after calling this method.

Implemented in io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.

◆ getDeferredComponentInstallState()

abstract String io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.getDeferredComponentInstallState ( int  loadingUnitId,
String  componentName 
)
abstract

Gets the current state of the installation session corresponding to the specified loadingUnitId and/or componentName.

Invocations of installDeferredComponent typically result in asynchronous downloading and other tasks. This method enables querying of the state of the installation. Querying the installation state is purely informational and does not impact the installation process. The results of this query should not be used to decide if the deferred component is ready to use. Upon completion of installation, the Future returned by the installation request will complete. Only after dart Future completion is it safe to use code and assets from the deferred component.

If no deferred component has been installed or requested to be installed by the provided loadingUnitId or componentName, then this method will return null.

Depending on the implementation, the returned String may vary. The Play store default implementation begins in the "requested" state before transitioning to the "downloading" and "installed" states.

Only successfully requested components have state. Modules that are invalid or have not been requested with installDeferredComponent will not have a state. Due to the asynchronous nature of the download process, components may not immediately have a valid state upon return of installDeferredComponent, though valid components will eventually obtain a state.

Both parameters are not always necessary to identify which component to install. Asset-only components do not have an associated loadingUnitId. Instead, an invalid ID like -1 may be passed to query only with componentName. On the other hand, it can be possible to resolve the componentName based on the loadingUnitId. This resolution is done if componentName is null. At least one of loadingUnitId or componentName must be valid or non-null.

Parameters
loadingUnitIdThe unique identifier associated with a Dart deferred library.
componentNameThe deferred component name as defined in bundle_config.yaml.

◆ installDeferredComponent()

abstract void io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.installDeferredComponent ( int  loadingUnitId,
String  componentName 
)
abstract

Request that the deferred component be downloaded and installed.

This method begins the download and installation of the specified deferred component. For example, the Play Store dynamic delivery implementation uses SplitInstallManager to request the download of the component. Download is not complete when this method returns. The download process should be listened for and upon completion of download, listeners should invoke loadAssets first and then loadDartLibrary to complete the deferred component load process. Assets-only deferred components should also call DeferredComponentChannel.completeInstallSuccess or DeferredComponentChannel.completeInstallError to complete the method channel invocation's dart Future.

Both parameters are not always necessary to identify which component to install. Asset-only components do not have an associated loadingUnitId. Instead, an invalid ID like -1 may be passed to download only with componentName. On the other hand, it can be possible to resolve the componentName based on the loadingUnitId. This resolution is done if componentName is null. At least one of loadingUnitId or componentName must be valid or non-null.

Flutter will typically call this method in two ways. When invoked as part of a dart loadLibrary() call, a valid loadingUnitId is passed in while the componentName is null. In this case, this method is responsible for figuring out what component the loadingUnitId corresponds to.

When invoked manually as part of loading an assets-only component, loadingUnitId is -1 (invalid) and componentName is supplied. Without a loadingUnitId, this method just downloads the component by name and attempts to load assets via loadAssets while loadDartLibrary is skipped, even if the deferred component includes valid dart libs. To load dart libs, call loadLibrary() using the first way described in the previous paragraph as the method channel invocation will not load dart shared libraries.

While the Future retuned by either loadLibary or the method channel invocation will indicate when the code and assets are ready to be used, informational querying of the install process' state can be done with getDeferredComponentInstallState, though the results of this query should not be used to decide if the deferred component is ready to use. Only the Future completion should be used to do this.

Parameters
loadingUnitIdThe unique identifier associated with a Dart deferred library. This id is assigned by the compiler and can be seen for reference in bundle_config.yaml. This ID is primarily used in loadDartLibrary to indicate to Dart which Dart library is being loaded. Loading unit ids range from 0 to the number existing loading units. Passing a negative loading unit id indicates that no Dart deferred library should be loaded after download completes. This is the case when the deferred component is an assets-only component. If a negative loadingUnitId is passed, then componentName must not be null. Passing a loadingUnitId larger than the highest valid loading unit's id will cause the Dart loadLibrary() to complete with a failure.
componentNameThe deferred component name as defined in bundle_config.yaml. This may be null if the deferred component to be loaded is associated with a loading unit/deferred dart library. In this case, it is this method's responsibility to map the loadingUnitId to its corresponding componentName. When loading asset-only or other deferred components without an associated Dart deferred library, loading unit id should a negative value and componentName must be non-null.

◆ loadAssets()

abstract void io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadAssets ( int  loadingUnitId,
String  componentName 
)
abstract

Extract and load any assets and resources from the deferred component for use by Flutter.

This method should provide a refreshed AssetManager to FlutterJNI.updateAssetManager that can access the new assets. If no assets are included as part of the deferred component, then nothing needs to be done.

If using the Play Store deferred component delivery, refresh the context via:
context.createPackageContext(context.getPackageName(), 0);
This returns a new context, from which an updated asset manager may be obtained and passed to updateAssetManager in FlutterJNI. This process does not require loadingUnitId or componentName, however, the two parameters are still present for custom implementations that store assets outside of Android's native system.

Assets shoud be loaded before the Dart deferred library is loaded, as successful loading of the Dart loading unit indicates the deferred component is fully loaded. Implementations of installDeferredComponent should invoke this after successful download.

Parameters
loadingUnitIdThe unique identifier associated with a Dart deferred library.
componentNameThe deferred component name as defined in bundle_config.yaml.

◆ loadDartLibrary()

abstract void io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.loadDartLibrary ( int  loadingUnitId,
String  componentName 
)
abstract

Load the .so shared library file into the Dart VM.

When the download of a deferred component completes, this method should be called to find the path .so library file. The path(s) should then be passed to FlutterJNI.loadDartDeferredLibrary to be dlopen-ed and loaded into the Dart VM.

Specifically, APKs distributed by Android's app bundle format may vary by device and API number, so FlutterJNI's loadDartDeferredLibrary accepts a list of search paths with can include paths within APKs that have not been unpacked using the path/to/apk.apk!path/inside/apk/lib.so format. Each search path will be attempted in order until a shared library is found. This allows for the developer to avoid unpacking the apk zip.

Upon successful load of the Dart library, the Dart future from the originating loadLibary() call completes and developers are able to use symbols and assets from the deferred component.

Parameters
loadingUnitIdThe unique identifier associated with a Dart deferred library. This id is assigned by the compiler and can be seen for reference in bundle_config.yaml. This ID is primarily used in loadDartLibrary to indicate to Dart which Dart library is being loaded. Loading unit ids range from 0 to the number existing loading units. Negative loading unit ids are considered invalid and this method will result in a no-op.
componentNameThe deferred component name as defined in bundle_config.yaml. If using Play Store deferred component delivery, this name corresponds to the root name on the installed APKs in which to search for the desired shared library .so file.

◆ setDeferredComponentChannel()

abstract void io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.setDeferredComponentChannel ( DeferredComponentChannel  channel)
abstract

Sets the DeferredComponentChannel system channel to handle the framework API to directly call methods in DeferredComponentManager.

A DeferredComponentChannel is required to handle assets-only deferred components and manually installed deferred components.

Since this class may be instantiated for injection before the FlutterEngine and System Channels are initialized, this method should be called to provide the DeferredComponentChannel. Similarly, the DeferredComponentChannel.setDeferredComponentManager method should also be called with this DeferredComponentManager instance to properly forward method invocations.

The DeferredComponentChannel passes manual invocations of installDeferredComponent and getDeferredComponentInstallState from the method channel to this DeferredComponentManager. Upon completion of the install process, successful installations should notify the DeferredComponentChannel by calling DeferredComponentChannel.completeInstallSuccess while errors and failures should call DeferredComponentChannel.completeInstallError.

◆ setJNI()

abstract void io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.setJNI ( FlutterJNI  flutterJNI)
abstract

Sets the FlutterJNI to be used to communication with the Flutter native engine.

A FlutterJNI is required in order to properly execute loadAssets and loadDartLibrary.

Since this class may be instantiated for injection before the FlutterEngine and FlutterJNI is fully initialized, this method should be called to provide the FlutterJNI instance to use for use in loadDartLibrary and loadAssets.

◆ uninstallDeferredComponent()

abstract boolean io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.uninstallDeferredComponent ( int  loadingUnitId,
String  componentName 
)
abstract

Request that the specified component be uninstalled.

Since uninstallation requires significant disk i/o, this method only signals the intent to uninstall. Actual uninstallation (eg, removal of assets and files) may occur at a later time. However, once uninstallation is requested, the deferred component should not be used anymore until installDeferredComponent is called again.

Uninstallation, once complete, removes downloaded files and will require redownloading to install again.

Both parameters are not always necessary to identify which component to uninstall. Asset-only components do not have an associated loadingUnitId. Instead, an invalid ID like -1 may be passed to download only with componentName. On the other hand, it can be possible to resolve the componentName based on the loadingUnitId. This resolution is done if componentName is null. At least one of loadingUnitId or componentName must be valid or non-null.

Returns
false if no deferred component was found matching the input, true if an uninstall was successfully requested.
Parameters
loadingUnitIdThe unique identifier associated with a Dart deferred library.
componentNameThe deferred component name as defined in bundle_config.yaml.

The documentation for this interface was generated from the following file: