diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index d26663fe9ccb..02b257d6b168 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 f5ee180ab1fd..f47b8e57b049 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 @@ class GoogleMapController { Future 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 5cf3db120ccd..d7f0f1a4e280 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 @@ -251,6 +251,13 @@ class _GoogleMapState extends State { _circles = keyByCircleId(widget.circles); } + @override + void dispose() async { + super.dispose(); + GoogleMapController controller = await _controller.future; + controller.dispose(); + } + @override void didUpdateWidget(GoogleMap oldWidget) { super.didUpdateWidget(oldWidget); diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index a33efb9d8e2c..e7e3aeeb3327 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 7861c86e9709..5ea9a679a1be 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 @@ void main() { 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 @@ void main() { ), ]); }); + + 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 extends Mock implements Stream {} + +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()); + when(platform.onCameraMove(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onCameraMoveStarted(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onCircleTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onInfoWindowTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onLongPress(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onMarkerDragEnd(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onMarkerTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onPolygonTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onPolylineTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); }