我一直在开发一个包含 Google 地图小部件的 Flutter 项目。最初,我遇到了一些与地图渲染相关的警告和错误,具体来说:
E/FrameEvents(10551): updateAcquireFence: Did not find frame.
W/Parcel (10551): Expecting binder but got null!
这些错误始终出现,似乎与 Google 地图小部件的渲染过程有关。
初步实施 这是我的 Flutter 应用程序中 Google 地图小部件的初始实现:
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();
}
}
解决方案:混合组合 经过研究和故障排除后,我发现为 Google 地图小部件启用混合组合可以解决这些问题。混合合成有助于利用平台的本机视图进行渲染,这可以解决各种渲染问题,包括上面提到的问题。
这是启用混合组合的更新后的代码:
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
),
),
);
}
}
解释 在 initState 方法中,我添加了一个函数 _initializeMapRenderer() ,它将 useAndroidViewSurface 设置为 true。这使得 Android 上的 Google 地图小部件能够实现混合组合。这是关键部分:
void _initializeMapRenderer() {
final GoogleMapsFlutterPlatform mapsImplementation = GoogleMapsFlutterPlatform.instance;
if (mapsImplementation is GoogleMapsFlutterAndroid) {
mapsImplementation.useAndroidViewSurface = true;
}
}
通过启用此功能,可以解决 updateAcquireFence 和 Expecting binder but getting null 错误,从而实现更流畅的性能并且不会出现渲染警告。
结论 如果您在 Flutter 应用程序中的 Google Maps 小部件中遇到类似的错误,请尝试使用 useAndroidViewSurface 启用混合组合。这个小小的改变可以显着提高渲染性能并消除与地图渲染过程相关的常见错误和警告。
我还收到运行时错误:
E/FrameEvents(10551): updateAcquireFence: Did not find frame.
但我意识到,在您获取 API 密钥的 Google 开发者控制台中 - 即使我使用不受限制的 API 密钥进行测试,该密钥所在的项目也没有启用 Maps SDK For Android 产品(在 API 下)和服务)。我只启用了 Javascript,因为我正在重用该项目。
添加该权限后,我的简化应用程序(OP 的原始应用程序)将渲染地图,并且不会向带有该错误的日志发送垃圾邮件。