Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
49667ba2
Unverified
Commit
49667ba2
authored
Jan 13, 2021
by
Gary Qian
Committed by
GitHub
Jan 13, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DeferredComponent utility class for manual handling of Deferred Components (#72895)
parent
388dcd24
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
155 additions
and
12 deletions
+155
-12
services.dart
packages/flutter/lib/services.dart
+1
-0
deferred_component.dart
packages/flutter/lib/src/services/deferred_component.dart
+100
-0
system_channels.dart
packages/flutter/lib/src/services/system_channels.dart
+12
-12
deferred_component_test.dart
packages/flutter/test/services/deferred_component_test.dart
+42
-0
No files found.
packages/flutter/lib/services.dart
View file @
49667ba2
...
...
@@ -15,6 +15,7 @@ export 'src/services/autofill.dart';
export
'src/services/binary_messenger.dart'
;
export
'src/services/binding.dart'
;
export
'src/services/clipboard.dart'
;
export
'src/services/deferred_component.dart'
;
export
'src/services/font_loader.dart'
;
export
'src/services/haptic_feedback.dart'
;
export
'src/services/keyboard_key.dart'
;
...
...
packages/flutter/lib/src/services/deferred_component.dart
0 → 100644
View file @
49667ba2
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'system_channels.dart'
;
/// Manages the installation and loading of deferred component modules.
///
/// Deferred components allow Flutter applications to download precompiled AOT
/// dart code and assets at runtime, reducing the install size of apps and
/// avoiding installing unnessecary code/assets on end user devices. Common
/// use cases include deferring installation of advanced or infrequently
/// used features and limiting locale specific features to users of matching
/// locales. Deferred components can only deliver split off parts of the same
/// app that was built and installed on the device. It cannot load new code
/// written after the app is distributed.
///
/// Deferred components are currently an Android-only feature. The methods in
/// this class are a no-op and all assets and dart code are already available
/// without installation if called on other platforms.
class
DeferredComponent
{
// This class is not meant to be instantiated or extended; this constructor
// prevents instantiation and extension.
DeferredComponent
.
_
();
// TODO(garyq): We should eventually expand this to install modules by loadingUnitId
// as well as moduleName, but currently, loadingUnitId is opaque to the dart code
// so this is not possible. The API has been left flexible to allow adding
// loadingUnitId as a parameter.
/// Requests that an assets-only deferred component identified by the [moduleName]
/// be downloaded and installed.
///
/// This method returns a Future<void> that will complete when the feature is
/// installed and any assets are ready to be used. When an error occurs, the
/// future will complete with an error.
///
/// This method should be used for asset-only deferred components or loading just
/// the assets from a component with both dart code and assets. Deferred components
/// containing dart code should call `loadLibrary()` on a deferred imported
/// library's prefix to ensure that the dart code is properly loaded as
/// `loadLibrary()` will provide the loading unit id needed for the dart
/// library loading process. For example:
///
/// ```dart
/// import 'split_module.dart' deferred as SplitModule;
/// ...
/// SplitModule.loadLibrary();
/// ```
///
/// This method will not load associated dart libraries contained in the dynamic
/// feature module, though it will download the files necessary and subsequent
/// calls to `loadLibrary()` to load will complete faster.
///
/// Assets installed by this method may be accessed in the same way as any other
/// local asset by providing a string path to the asset.
///
/// See also:
///
/// * [uninstallDeferredComponent], a method to request the uninstall of a component.
/// * [loadLibrary](https://api.dart.dev/dart-mirrors/LibraryDependencyMirror/loadLibrary.html),
/// the dart method to trigger the installation of the corresponding deferred component that
/// contains the dart library.
static
Future
<
void
>
installDeferredComponent
({
required
String
moduleName
})
async
{
await
SystemChannels
.
deferredComponent
.
invokeMethod
<
void
>(
'installDeferredComponent'
,
<
String
,
dynamic
>{
'loadingUnitId'
:
-
1
,
'moduleName'
:
moduleName
},
);
}
/// Requests that a deferred component identified by the [moduleName] be
/// uninstalled.
///
/// Since uninstallation typically requires significant disk i/o, this method only
/// signals the intent to uninstall. Completion of the returned future indicates
/// that the request to uninstall has been registered. Actual uninstallation (e.g.,
/// 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] or `loadLibrary()` is called again.
///
/// It is safe to request an uninstall when dart code from the component is in use,
/// but assets from the component should not be used once the component uninstall is
/// requested. The dart code will remain usable in the app's current session but
/// is not guaranteed to work in future sessions.
///
/// See also:
///
/// * [installDeferredComponent], a method to install asset-only components.
/// * [loadLibrary](https://api.dart.dev/dart-mirrors/LibraryDependencyMirror/loadLibrary.html),
/// the dart method to trigger the installation of the corresponding deferred component that
/// contains the dart library.
static
Future
<
void
>
uninstallDeferredComponent
({
required
String
moduleName
})
async
{
await
SystemChannels
.
deferredComponent
.
invokeMethod
<
void
>(
'uninstallDeferredComponent'
,
<
String
,
dynamic
>{
'loadingUnitId'
:
-
1
,
'moduleName'
:
moduleName
},
);
}
}
packages/flutter/lib/src/services/system_channels.dart
View file @
49667ba2
...
...
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:ui'
;
import
'message_codecs.dart'
;
...
...
@@ -319,29 +318,30 @@ class SystemChannels {
StandardMethodCodec
(),
);
/// A [MethodChannel] for installing and managing d
ynamic feature
s.
/// A [MethodChannel] for installing and managing d
eferred component
s.
///
/// The following outgoing methods are defined for this channel (invoked using
/// [OptionalMethodChannel.invokeMethod]):
///
/// * `installD
ynamicFeature`: Requests that a dynamic feature
identified by
/// * `installD
eferredComponent`: Requests that a deferred component
identified by
/// the provided loadingUnitId or moduleName be downloaded and installed.
/// Providing a loadingUnitId with null moduleName will install a dynamic
/// feature module that includes the desired loading unit. If a moduleName
/// is provided, then the d
ynamic feature
with the moduleName will be installed.
/// is provided, then the d
eferred component
with the moduleName will be installed.
/// This method returns a future that will not be completed until the
/// feature is fully installed and ready to use. When an error occurs, the
/// future will complete an error. Calling `loadLibrary()` on a deferred
/// imported library is equivalent to calling this method with a
/// loadingUnitId and null moduleName.
/// * `getDynamicFeatureInstallState`: Gets the current installation state of
/// the dynamic feature identified by the loadingUnitId or moduleName.
/// This method returns a string that represents the state. Depending on
/// the implementation, this string may vary, but the default Google Play
/// Store implementation beings in the "Requested" state before transitioning
/// into the "Downloading" and finally the "Installed" state.
static
const
MethodChannel
dynamicfeature
=
OptionalMethodChannel
(
'flutter/dynamicfeature'
,
/// * `uninstallDeferredComponent`: Requests that a deferred component identified by
/// the provided loadingUnitId or moduleName be uninstalled. Since
/// uninstallation typically 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` or `loadLibrary` is called again.
static
const
MethodChannel
deferredComponent
=
OptionalMethodChannel
(
'flutter/deferredcomponent'
,
StandardMethodCodec
(),
);
}
packages/flutter/test/services/deferred_component_test.dart
0 → 100644
View file @
49667ba2
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/services.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
TestWidgetsFlutterBinding
.
ensureInitialized
();
test
(
'installDeferredComponent test'
,
()
async
{
final
List
<
MethodCall
>
log
=
<
MethodCall
>[];
SystemChannels
.
deferredComponent
.
setMockMethodCallHandler
((
MethodCall
methodCall
)
async
{
log
.
add
(
methodCall
);
});
await
DeferredComponent
.
installDeferredComponent
(
moduleName:
'testModuleName'
);
expect
(
log
,
hasLength
(
1
));
expect
(
log
.
single
,
isMethodCall
(
'installDeferredComponent'
,
arguments:
<
String
,
dynamic
>{
'loadingUnitId'
:
-
1
,
'moduleName'
:
'testModuleName'
},
));
});
test
(
'uninstallDeferredComponent test'
,
()
async
{
final
List
<
MethodCall
>
log
=
<
MethodCall
>[];
SystemChannels
.
deferredComponent
.
setMockMethodCallHandler
((
MethodCall
methodCall
)
async
{
log
.
add
(
methodCall
);
});
await
DeferredComponent
.
uninstallDeferredComponent
(
moduleName:
'testModuleName'
);
expect
(
log
,
hasLength
(
1
));
expect
(
log
.
single
,
isMethodCall
(
'uninstallDeferredComponent'
,
arguments:
<
String
,
dynamic
>{
'loadingUnitId'
:
-
1
,
'moduleName'
:
'testModuleName'
},
));
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment