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.
|
/// used with one parser for the lifetime of the asset bundle.
|
||||||
Future<dynamic> loadStructuredData(String key, dynamic parser(String value));
|
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
|
@override
|
||||||
String toString() => '$runtimeType@$hashCode()';
|
String toString() => '$runtimeType@$hashCode()';
|
||||||
}
|
}
|
||||||
@ -101,6 +106,9 @@ class NetworkAssetBundle extends AssetBundle {
|
|||||||
return parser(await loadString(key));
|
return parser(await loadString(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(ianh): Once the underlying network logic learns about caching, we
|
||||||
|
// should implement evict().
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => '$runtimeType@$hashCode($_baseUrl)';
|
String toString() => '$runtimeType@$hashCode($_baseUrl)';
|
||||||
}
|
}
|
||||||
@ -155,6 +163,12 @@ abstract class CachingAssetBundle extends AssetBundle {
|
|||||||
});
|
});
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void evict(String key) {
|
||||||
|
_stringCache.remove(key);
|
||||||
|
_structuredDataCache.remove(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An [AssetBundle] that loads resources from a Mojo service.
|
/// An [AssetBundle] that loads resources from a Mojo service.
|
||||||
|
@ -7,6 +7,7 @@ import 'dart:async';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
import 'asset_bundle.dart';
|
import 'asset_bundle.dart';
|
||||||
|
import 'image_cache.dart';
|
||||||
import 'shell.dart';
|
import 'shell.dart';
|
||||||
|
|
||||||
/// Ensures that the [MojoShell] singleton is created synchronously
|
/// 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;
|
/// 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
|
/// if not, calls the given callback to obtain it first. In either case, the
|
||||||
/// key is moved to the "most recently used" position.
|
/// key is moved to the "most recently used" position.
|
||||||
|
@ -731,6 +731,28 @@ abstract class State<T extends StatefulWidget> {
|
|||||||
@protected
|
@protected
|
||||||
void didUpdateConfig(T oldConfig) { }
|
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.
|
/// Notify the framework that the internal state of this object has changed.
|
||||||
///
|
///
|
||||||
/// Whenever you change the internal state of a [State] object, make the
|
/// Whenever you change the internal state of a [State] object, make the
|
||||||
@ -2061,6 +2083,7 @@ class StatefulElement extends ComponentElement {
|
|||||||
@override
|
@override
|
||||||
void _reassemble() {
|
void _reassemble() {
|
||||||
_builder = state.build;
|
_builder = state.build;
|
||||||
|
state.reassemble();
|
||||||
super._reassemble();
|
super._reassemble();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +205,12 @@ class _ImageState extends State<Image> {
|
|||||||
super.dependenciesChanged();
|
super.dependenciesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void reassemble() {
|
||||||
|
_resolveImage();
|
||||||
|
super.reassemble();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_imageStream.removeListener(_handleImageChanged);
|
_imageStream.removeListener(_handleImageChanged);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user