Flutter中返回Future<dynamic>的异步函数如何获取UserLocation对象?
Flutter 定位函数调用解决方案
第一步:优化原函数返回类型
你当前的问题根源是原函数未声明明确返回类型,且权限、服务校验失败分支返回值未明确,首先将函数返回类型修改为Future<UserLocation?>,空值代表定位失败场景,修改后代码如下:
// 明确声明返回类型为可空的UserLocation异步结果 Future<UserLocation?> getUserLocation() async { bool _serviceEnabled; loc.PermissionStatus _permissionGranted; // 建议将abbr设为局部变量,避免全局变量污染 String abbr = ""; loc.LocationData? _currentPosition; _serviceEnabled = await location.serviceEnabled(); if (!_serviceEnabled) { _serviceEnabled = await location.requestService(); if (!_serviceEnabled) { // 服务未开启返回空 return null; } } _permissionGranted = await location.hasPermission(); if (_permissionGranted == loc.PermissionStatus.denied) { _permissionGranted = await location.requestPermission(); if (_permissionGranted != loc.PermissionStatus.granted) { // 权限未通过返回空 return null; } } try { _currentPosition = await location.getLocation(); } catch (e) { print(e); // 定位异常返回空 return null; } if (_currentPosition == null) return null; List<geo.Placemark> placemarks = await geo.placemarkFromCoordinates( _currentPosition.latitude ?? 0, _currentPosition.longitude ?? 0); // 新增空判断避免数组越界 if (placemarks.isEmpty) return null; var countryNameList = placemarks[0].country?.split(' '); if (countryNameList == null || countryNameList.isEmpty) return null; if (countryNameList.length >= 2) { for (var eachLetter in countryNameList) { if (eachLetter.isNotEmpty) abbr += eachLetter[0]; } } else { abbr = countryNameList.first.substring(0, 2).toUpperCase(); } return UserLocation( city: placemarks[0].locality ?? 'Chennai', country: abbr, latitude: _currentPosition.latitude, longitude: _currentPosition.longitude); }
第二步:正确调用函数获取返回值
有两种常用调用方式可选:
方式1:async/await 调用(推荐)
在调用方法上添加async修饰符,用await等待异步结果返回后做空校验:
// 示例:按钮点击事件中调用 void onLocationButtonTap() async { UserLocation? result = await getUserLocation(); if (result != null) { // 非空判定后可直接使用UserLocation对象,示例如下 debugPrint("定位成功,当前城市:${result.city},国家缩写:${result.country}"); // 后续业务逻辑写在此处 } else { // 定位失败的兜底逻辑,比如弹提示告知用户 debugPrint("定位失败,请检查定位服务和权限是否开启"); } }
方式2:then链式调用
如果无法给调用方法添加async修饰,可使用链式调用处理异步结果:
getUserLocation().then((result) { if (result != null) { // 定位成功业务逻辑 } else { // 定位失败兜底逻辑 } });
内容的提问来源于stack exchange,提问作者Divyam Dhadwal
相关产品推荐
相关产品推荐

