fix #25143 Successive calls to `precacheImage()` throw an exception (#25159)

diff --git a/AUTHORS b/AUTHORS
index 67cc5d4..ec25d3e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -32,3 +32,4 @@
 Stefan Mitev <mr.mitew@gmail.com>
 Jasper van Riet <jaspervanriet@gmail.com>
 Mattijs Fuijkschot <mattijs.fuijkschot@gmail.com>
+TruongSinh Tran-Nguyen <i@truongsinh.pro>
diff --git a/packages/flutter/lib/src/widgets/image.dart b/packages/flutter/lib/src/widgets/image.dart
index 9711823..b7d068a 100644
--- a/packages/flutter/lib/src/widgets/image.dart
+++ b/packages/flutter/lib/src/widgets/image.dart
@@ -83,9 +83,11 @@
   final ImageStream stream = provider.resolve(config);
   void listener(ImageInfo image, bool sync) {
     completer.complete();
+    stream.removeListener(listener);
   }
   void errorListener(dynamic exception, StackTrace stackTrace) {
     completer.complete();
+    stream.removeListener(listener);
     if (onError != null) {
       onError(exception, stackTrace);
     } else {
@@ -99,7 +101,6 @@
     }
   }
   stream.addListener(listener, onError: errorListener);
-  completer.future.then<void>((void value) { stream.removeListener(listener); });
   return completer.future;
 }
 
diff --git a/packages/flutter/test/widgets/image_test.dart b/packages/flutter/test/widgets/image_test.dart
index 7c17a95..f0b9ea4 100644
--- a/packages/flutter/test/widgets/image_test.dart
+++ b/packages/flutter/test/widgets/image_test.dart
@@ -621,6 +621,28 @@
     expect(isSync, isTrue);
   });
 
+  testWidgets('Precache remove listeners immediately after future completes, does not crash on successive calls #25143', (WidgetTester tester) async {
+    final TestImageStreamCompleter imageStreamCompleter = TestImageStreamCompleter();
+    final TestImageProvider provider = TestImageProvider(streamCompleter: imageStreamCompleter);
+
+    await tester.pumpWidget(
+      Builder(
+        builder: (BuildContext context) {
+          precacheImage(provider, context);
+          return Container();
+        }
+      )
+    );
+
+    expect(imageStreamCompleter.listeners.length, 2);
+    imageStreamCompleter.listeners.keys.toList()[1](null, null);
+
+    expect(imageStreamCompleter.listeners.length, 1);
+    imageStreamCompleter.listeners.keys.toList()[0](null, null);
+
+    expect(imageStreamCompleter.listeners.length, 0);
+  });
+
   testWidgets('Precache completes with onError on error', (WidgetTester tester) async {
     dynamic capturedException;
     StackTrace capturedStackTrace;