Flutter如何使用函数异步返回值 定位权限校验跳转代码是否正确
现有代码问题说明
你的核心业务逻辑符合需求,但存在4处可优化的问题,部分问题会直接导致需求不达标:
- 异步逻辑未等待:
checkLocation方法中调用的updateSettingLocation是异步方法,现有代码没有加await就直接执行跳转,会出现跳转到首页后定位还未写入SharedPreferences的情况,不符合你要求的「先存定位再跳转」的逻辑 - 存在冗余代码:
currentLocation和updateCurrentLocation功能完全重复,都是获取高精度定位后写入存储,不需要两套实现 - 权限判断逻辑可优化:现有逻辑把「定位服务未开启」和「权限未授权」统一归为未授权跳转权限申请页,实际上定位服务没开时应该引导用户开启系统定位,而不是申请权限,可拆分逻辑优化体验
- initState直接使用context有风险:Flutter在initState生命周期阶段widget还未完全挂载到渲染树,直接使用context可能出现异常,建议包裹在
addPostFrameCallback中执行
优化后代码
@override void initState() { super.initState(); // 等待界面渲染完成后再执行逻辑,避免context异常 WidgetsBinding.instance.addPostFrameCallback((_) async { await checkLocation(context); }); } Future<void> checkLocation(BuildContext context) async { bool isGranted = await checkLocationPermission(); if(isGranted) { // 等待定位获取并存储完成后再跳转 await updateSettingLocation(); if(context.mounted) { // 加mounted判断,避免页面销毁后执行跳转报错 Navigator.of(context).pushNamed('/homepage'); } } else { if(context.mounted) { Navigator.of(context).pushNamed('/location'); } } } Future<void> updateSettingLocation() async { final location = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); if (location != null) { print("Location: ${location.latitude},${location.longitude}"); await settingsRepo.setCurrentLocation(location); } } Future<bool> checkLocationPermission() async { // 先判断定位服务是否开启 bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { print('定位服务未开启'); return false; } // 再判断权限状态 LocationPermission permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) { print('定位权限未授权'); return false; } print('定位权限已授权'); return true; }
额外注意点
- 跳转前加
context.mounted判断是为了避免异步执行过程中当前页面被销毁,调用Navigator出现的异常 - 写入SharedPreferences的
setCurrentLocation方法如果是异步的,建议也加上await保证写入完成再跳转
内容的提问来源于stack exchange,提问作者Ismail Muhammad
相关产品推荐
相关产品推荐

