Provide an observatory extension to evict resources (#5241)
...so that you can use hot reload mode to update assets.
This commit is contained in:
parent
357f85af99
commit
95f2e981da
@ -62,6 +62,11 @@ abstract class AssetBundle {
|
||||
/// used with one parser for the lifetime of the asset bundle.
|
||||
Future<dynamic> loadStructuredData(String key, dynamic parser(String value));
|
||||
|
||||
/// If this is a caching asset bundle, and the given key describes a cached
|
||||
/// asset, then evict the asset from the cache so that the next time it is
|
||||
/// loaded, the cache will be reread from the asset bundle.
|
||||
void evict(String key) { }
|
||||
|
||||
@override
|
||||
String toString() => '$runtimeType@$hashCode()';
|
||||
}
|
||||
@ -101,6 +106,9 @@ class NetworkAssetBundle extends AssetBundle {
|
||||
return parser(await loadString(key));
|
||||
}
|
||||
|
||||
// TODO(ianh): Once the underlying network logic learns about caching, we
|
||||
// should implement evict().
|
||||
|
||||
@override
|
||||
String toString() => '$runtimeType@$hashCode($_baseUrl)';
|
||||
}
|
||||
@ -155,6 +163,12 @@ abstract class CachingAssetBundle extends AssetBundle {
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
@override
|
||||
void evict(String key) {
|
||||
_stringCache.remove(key);
|
||||
_structuredDataCache.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/// An [AssetBundle] that loads resources from a Mojo service.
|
||||
|
@ -7,6 +7,7 @@ import 'dart:async';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'asset_bundle.dart';
|
||||
import 'image_cache.dart';
|
||||
import 'shell.dart';
|
||||
|
||||
/// Ensures that the [MojoShell] singleton is created synchronously
|
||||
@ -47,4 +48,21 @@ abstract class ServicesBinding extends BindingBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initServiceExtensions() {
|
||||
super.initServiceExtensions();
|
||||
registerStringServiceExtension(
|
||||
// ext.flutter.evict value=foo.png will cause foo.png to be evicted from the rootBundle cache
|
||||
// and cause the entire image cache to be cleared. This is used by hot reload mode to clear
|
||||
// out the cache of resources that have changed.
|
||||
// TODO(ianh): find a way to only evict affected images, not all images
|
||||
name: 'evict',
|
||||
getter: () => '',
|
||||
setter: (String value) {
|
||||
rootBundle.evict(value);
|
||||
imageCache.clear();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,16 @@ class ImageCache {
|
||||
}
|
||||
}
|
||||
|
||||
/// Evicts all entries from the cache.
|
||||
///
|
||||
/// This is useful if, for instance, the root asset bundle has been updated
|
||||
/// and therefore new images must be obtained.
|
||||
// TODO(ianh): Provide a way to target individual images. This is currently non-trivial
|
||||
// because by the time we get to the imageCache, the keys we're using are opaque.
|
||||
void clear() {
|
||||
_cache.clear();
|
||||
}
|
||||
|
||||
/// Returns the previously cached [ImageStream] for the given key, if available;
|
||||
/// if not, calls the given callback to obtain it first. In either case, the
|
||||
/// key is moved to the "most recently used" position.
|
||||
|
@ -731,6 +731,28 @@ abstract class State<T extends StatefulWidget> {
|
||||
@protected
|
||||
void didUpdateConfig(T oldConfig) { }
|
||||
|
||||
/// Called whenever the application is reassembled during debugging.
|
||||
///
|
||||
/// This method should rerun any initialization logic that depends on global
|
||||
/// state, for example, image loading from asset bundles (since the asset
|
||||
/// bundle may have changed).
|
||||
///
|
||||
/// In addition to this method being invoked, it is guaranteed that the
|
||||
/// [build] method will be invoked when a reassemble is signalled. Most
|
||||
/// widgets therefore do not need to do anything in the [reassemble] method.
|
||||
///
|
||||
/// This function will only be called during development. In release builds,
|
||||
/// the `ext.flutter.reassemble` hook is not available, and so this code will
|
||||
/// never execute.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [BindingBase.reassembleApplication]
|
||||
/// * [Image], which uses this to reload images
|
||||
@protected
|
||||
@mustCallSuper
|
||||
void reassemble() { }
|
||||
|
||||
/// Notify the framework that the internal state of this object has changed.
|
||||
///
|
||||
/// Whenever you change the internal state of a [State] object, make the
|
||||
@ -2061,6 +2083,7 @@ class StatefulElement extends ComponentElement {
|
||||
@override
|
||||
void _reassemble() {
|
||||
_builder = state.build;
|
||||
state.reassemble();
|
||||
super._reassemble();
|
||||
}
|
||||
|
||||
|
@ -205,6 +205,12 @@ class _ImageState extends State<Image> {
|
||||
super.dependenciesChanged();
|
||||
}
|
||||
|
||||
@override
|
||||
void reassemble() {
|
||||
_resolveImage();
|
||||
super.reassemble();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_imageStream.removeListener(_handleImageChanged);
|
||||
|
Loading…
x
Reference in New Issue
Block a user