Flutter Google Maps场景下多类中Future的正确处理方法
解决Dart异步初始化导致的经纬度Null问题
你的问题核心在于构造函数是同步执行的,但获取位置是异步操作——当MapsService的构造函数执行到CameraPosition赋值时,LocationInfo里的latitude和longitude还没被异步回调赋值,自然是null,最终引发崩溃。下面是具体的重构方案:
第一步:重构LocationInfo,将异步逻辑移出构造函数
Dart的类构造函数不能是async的,所以我们把位置获取的逻辑放到一个单独的异步初始化方法中,或者用工厂构造函数直接返回Future<LocationInfo>:
class LocationInfo { Location location = Location(); LocationData? currentLocation; double? longitude; double? latitude; // 空的默认构造函数 LocationInfo(); // 异步初始化方法 Future<void> init() async { try { final locationData = await location.getLocation(); currentLocation = locationData; longitude = currentLocation?.longitude; latitude = currentLocation?.latitude; } catch (e) { currentLocation = null; longitude = null; latitude = null; } } // 可选:用工厂构造函数直接返回初始化完成的实例 factory LocationInfo.create() async { final info = LocationInfo(); await info.init(); return info; } }
第二步:修改MapsService,等待位置初始化完成再创建相机位置
同样,MapsService的构造函数也不能是async的,我们用工厂构造函数+私有异步初始化方法的组合,确保等待LocationInfo完成初始化后再赋值CameraPosition:
class MapsService { bool loading = false; LocationInfo? locationInfo; CameraPosition? cameraPosition; // 工厂构造函数,返回Future<MapsService> factory MapsService.create() async { final service = MapsService(); await service._init(); return service; } // 私有异步初始化方法 Future<void> _init() async { loading = true; // 方式1:用init方法 locationInfo = LocationInfo(); await locationInfo!.init(); // 方式2:用LocationInfo的工厂构造函数 // locationInfo = await LocationInfo.create(); // 给经纬度加默认值,避免获取失败时出现null cameraPosition = CameraPosition( zoom: 15, target: LatLng( locationInfo?.latitude ?? 0.0, locationInfo?.longitude ?? 0.0 ), ); loading = false; } }
第三步:使用MapsService的正确方式
现在不能直接用MapsService()创建实例,必须通过await MapsService.create()来获取初始化完成的对象。如果是在Flutter UI中使用,建议配合FutureBuilder处理异步状态:
FutureBuilder<MapsService>( future: MapsService.create(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text('获取位置失败:${snapshot.error}')); } else { final mapsService = snapshot.data!; return GoogleMap( initialCameraPosition: mapsService.cameraPosition!, // 其他地图配置... ); } }, )
关键说明
- 永远不要在同步构造函数里依赖异步回调的结果——回调会在构造函数执行完之后才触发,导致变量未初始化。
- 添加默认值(
?? 0.0)是为了处理位置获取失败的极端情况,避免即使等待完成后依然出现null的问题。
内容的提问来源于stack exchange,提问作者Ozan Taskiran
相关产品推荐
相关产品推荐

