Dispose precached image info (#143017)
`precacheImage` was failing to dipose the `ImageInfo` it receives. That's part of the contract of being an image listener.
I'm doing this in the frame callback for the same reason as evicting it from the cache.
diff --git a/packages/flutter/lib/src/widgets/image.dart b/packages/flutter/lib/src/widgets/image.dart
index c318050..5c2b88f 100644
--- a/packages/flutter/lib/src/widgets/image.dart
+++ b/packages/flutter/lib/src/widgets/image.dart
@@ -123,6 +123,7 @@
// image stream.
// See ImageCache._liveImages
SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) {
+ image?.dispose();
stream.removeListener(listener!);
}, debugLabel: 'precacheImage.removeListener');
},
diff --git a/packages/flutter/test/widgets/image_test.dart b/packages/flutter/test/widgets/image_test.dart
index 34b6e02..e92524a 100644
--- a/packages/flutter/test/widgets/image_test.dart
+++ b/packages/flutter/test/widgets/image_test.dart
@@ -798,8 +798,6 @@
});
testWidgets('Precache',
- // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean]
- experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(),
(WidgetTester tester) async {
final _TestImageProvider provider = _TestImageProvider();
late Future<void> precache;
@@ -818,7 +816,10 @@
// Check that a second resolve of the same image is synchronous.
final ImageStream stream = provider.resolve(provider._lastResolvedConfiguration);
late bool isSync;
- stream.addListener(ImageStreamListener((ImageInfo image, bool sync) { isSync = sync; }));
+ stream.addListener(ImageStreamListener((ImageInfo image, bool sync) {
+ image.dispose();
+ isSync = sync;
+ }));
expect(isSync, isTrue);
});
@@ -1565,8 +1566,6 @@
});
testWidgets('precacheImage does not hold weak ref for more than a frame',
- // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean]
- experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(),
(WidgetTester tester) async {
imageCache.maximumSize = 0;
final _TestImageProvider provider = _TestImageProvider();
@@ -1597,7 +1596,10 @@
expect(provider._lastResolvedConfiguration, isNotNull);
final ImageStream stream = provider.resolve(provider._lastResolvedConfiguration);
late bool isSync;
- final ImageStreamListener listener = ImageStreamListener((ImageInfo image, bool syncCall) { isSync = syncCall; });
+ final ImageStreamListener listener = ImageStreamListener((ImageInfo image, bool syncCall) {
+ image.dispose();
+ isSync = syncCall;
+ });
// Still have live ref because frame has not pumped yet.
await tester.pump();