I’ve been working on a Flutter project that includes a Google Maps widget. Initially, I encountered several warnings and errors related to the map rendering, specifically:
E/FrameEvents(10551): updateAcquireFence: Did not find frame.
W/Parcel (10551): Expecting binder but got null!
These errors appeared consistently and seemed to be related to the rendering process of the Google Map widget.
Initial Implementation
Here’s the initial implementation of the Google Maps widget in my Flutter app:
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class RecordMaps extends StatefulWidget {
final LatLng initialLocation;
RecordMaps({Key? key, required this.initialLocation}) : super(key: key);
@override
_RecordMapsState createState() => _RecordMapsState();
}
class _RecordMapsState extends State<RecordMaps> {
GoogleMapController? mapController;
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
_updateCamera();
}
void _updateCamera() {
mapController?.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(
target: widget.initialLocation,
zoom: 15.0,
),
));
}
@override
Widget build(BuildContext context) {
return GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: widget.initialLocation,
zoom: 15.0,
),
myLocationEnabled: true,
myLocationButtonEnabled: true,
);
}
@override
void dispose() {
mapController?.dispose();
super.dispose();
}
}
The Solution: Hybrid Composition
After researching and troubleshooting, I found that enabling hybrid composition for the Google Maps widget could resolve these issues. Hybrid composition helps by leveraging the platform’s native view for rendering, which can fix various rendering issues, including the ones mentioned above.
Here’s the updated code with hybrid composition enabled:
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
import 'package:google_maps_flutter_android/google_maps_flutter_android.dart';
class RecordMaps extends StatefulWidget {
final LatLng initialLocation;
RecordMaps({Key? key, required this.initialLocation}) : super(key: key);
@override
_RecordMapsState createState() => _RecordMapsState();
}
class _RecordMapsState extends State<RecordMaps> {
GoogleMapController? mapController;
@override
void initState() {
super.initState();
_initializeMapRenderer();
}
void _initializeMapRenderer() {
final GoogleMapsFlutterPlatform mapsImplementation = GoogleMapsFlutterPlatform.instance;
if (mapsImplementation is GoogleMapsFlutterAndroid) {
mapsImplementation.useAndroidViewSurface = true;
}
}
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
_updateCamera();
}
void _updateCamera() {
mapController?.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(
target: widget.initialLocation,
zoom: 15.0,
),
));
}
@override
void dispose() {
mapController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: widget.initialLocation,
zoom: 15.0,
),
myLocationEnabled: true,
myLocationButtonEnabled: true,
mapType: MapType.normal, // Use normal map type for simplicity
zoomControlsEnabled: false, // Disable zoom controls if not needed
compassEnabled: false, // Disable compass if not needed
),
),
);
}
}
Explanation
In the initState method, I added a function _initializeMapRenderer() which sets useAndroidViewSurface to true. This enables hybrid composition for the Google Maps widget on Android. Here’s the crucial part:
void _initializeMapRenderer() {
final GoogleMapsFlutterPlatform mapsImplementation = GoogleMapsFlutterPlatform.instance;
if (mapsImplementation is GoogleMapsFlutterAndroid) {
mapsImplementation.useAndroidViewSurface = true;
}
}
By enabling this, the updateAcquireFence and Expecting binder but got null errors were resolved, resulting in smoother performance and no rendering warnings.
Conclusion
If you are encountering similar errors with the Google Maps widget in your Flutter application, try enabling hybrid composition by using useAndroidViewSurface. This small change can significantly improve the rendering performance and eliminate common errors and warnings related to the map’s rendering process.