[google_maps_flutter] Call platform.dispose from widget. (#2909)
diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
index d26663f..02b257d 100644
--- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
+++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.5.30
+
+* Add a `dispose` method to the controller to let the native side know that we're done with said controller.
+* Call `controller.dispose()` from the `dispose` method of the `GoogleMap` widget.
+
## 0.5.29+1
* (ios) Pin dependency on GoogleMaps pod to `< 3.10`, to address https://github.com/flutter/flutter/issues/63447
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart
index f5ee180..f47b8e5 100644
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart
@@ -258,4 +258,9 @@
Future<Uint8List> takeSnapshot() {
return _googleMapsFlutterPlatform.takeSnapshot(mapId: mapId);
}
+
+ /// Disposes of the platform resources
+ void dispose() {
+ _googleMapsFlutterPlatform.dispose(mapId: mapId);
+ }
}
diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart
index 5cf3db1..d7f0f1a 100644
--- a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart
@@ -252,6 +252,13 @@
}
@override
+ void dispose() async {
+ super.dispose();
+ GoogleMapController controller = await _controller.future;
+ controller.dispose();
+ }
+
+ @override
void didUpdateWidget(GoogleMap oldWidget) {
super.didUpdateWidget(oldWidget);
_updateOptions();
diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
index a33efb9..e7e3aee 100644
--- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
+++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
@@ -1,13 +1,13 @@
name: google_maps_flutter
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter
-version: 0.5.29+1
+version: 0.5.30
dependencies:
flutter:
sdk: flutter
flutter_plugin_android_lifecycle: ^1.0.0
- google_maps_flutter_platform_interface: ^1.0.1
+ google_maps_flutter_platform_interface: ^1.0.4
dev_dependencies:
flutter_test:
diff --git a/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart
index 7861c86..5ea9a67 100644
--- a/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart
@@ -20,7 +20,8 @@
setUp(() {
// Use a mock platform so we never need to hit the MethodChannel code.
GoogleMapsFlutterPlatform.instance = platform;
- when(platform.buildView(any, any, any)).thenReturn(Container());
+ resetMockitoState();
+ _setupMock(platform);
});
testWidgets('_webOnlyMapCreationId increments with each GoogleMap widget', (
@@ -61,4 +62,60 @@
),
]);
});
+
+ testWidgets('Calls platform.dispose when GoogleMap is disposed of', (
+ WidgetTester tester,
+ ) async {
+ await tester.pumpWidget(GoogleMap(
+ initialCameraPosition: CameraPosition(
+ target: LatLng(43.3608, -5.8702),
+ ),
+ ));
+
+ // Now dispose of the map...
+ await tester.pumpWidget(Container());
+
+ verify(platform.dispose(mapId: anyNamed('mapId')));
+ });
+}
+
+// Some test setup classes below...
+
+class _MockStream<T> extends Mock implements Stream<T> {}
+
+typedef _CreationCallback = void Function(int);
+
+// Installs test mocks on the platform
+void _setupMock(MockGoogleMapsFlutterPlatform platform) {
+ // Used to create the view of the map...
+ when(platform.buildView(any, any, any)).thenAnswer((realInvocation) {
+ // Call the onPlatformViewCreated callback so the controller gets created.
+ _CreationCallback onPlatformViewCreatedCb =
+ realInvocation.positionalArguments[2];
+ onPlatformViewCreatedCb.call(0);
+ return Container();
+ });
+ // Used to create the Controller
+ when(platform.onCameraIdle(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<CameraIdleEvent>());
+ when(platform.onCameraMove(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<CameraMoveEvent>());
+ when(platform.onCameraMoveStarted(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<CameraMoveStartedEvent>());
+ when(platform.onCircleTap(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<CircleTapEvent>());
+ when(platform.onInfoWindowTap(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<InfoWindowTapEvent>());
+ when(platform.onLongPress(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<MapLongPressEvent>());
+ when(platform.onMarkerDragEnd(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<MarkerDragEndEvent>());
+ when(platform.onMarkerTap(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<MarkerTapEvent>());
+ when(platform.onPolygonTap(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<PolygonTapEvent>());
+ when(platform.onPolylineTap(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<PolylineTapEvent>());
+ when(platform.onTap(mapId: anyNamed('mapId')))
+ .thenAnswer((_) => _MockStream<MapTapEvent>());
}