Flutter:为何应用仅在热重启后才开始监听Geolocator位置流?
问题根因
- 你注释了位置权限校验逻辑,
initState执行getSpeedInMPH时,若用户还未授予位置权限,getPositionStream会直接静默失败,不会启动监听;热重启时权限已经授权完成,所以流程恢复正常 - 声明的
streamSubscription1未实际绑定监听实例,既无法处理监听异常,退出页面时也无法正常取消监听,会造成内存泄漏 - 速度值同步逻辑顺序错误,先向流中插入旧值才更新速度变量
修复方案
- 补充位置权限、位置服务校验逻辑,确认权限已授予后再启动位置流监听
- 把监听实例赋值给
streamSubscription1,增加异常处理逻辑 - 调整速度更新顺序,先计算最新速度再同步到状态和流中
修改后的核心代码如下:
// 新增位置权限与服务校验方法 Future<bool> _checkLocationPermission() async { bool serviceEnabled; LocationPermission permission; // 校验位置服务是否开启 serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { return false; } // 校验位置权限状态 permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { return false; } } if (permission == LocationPermission.deniedForever) { return false; } return true; } // 修改后的速度监听方法 void getSpeedInMPH() async { speedInMPH= 0.0; // 先校验权限,无权限直接返回 bool hasPermission = await _checkLocationPermission(); if (!hasPermission) { // 此处可自行补充无权限的提示逻辑 return; } // 把监听实例赋值给streamSubscription1,方便退出时取消 streamSubscription1 = Geolocator.getPositionStream( intervalDuration: const Duration(milliseconds: 2000), desiredAccuracy: LocationAccuracy.bestForNavigation ).listen( (position) { setState(() { speedInMPH = position.speed * 2.23693629; print('the Speed Stream are $speedInMPH'); }); // 先更新数值再同步到流 speedController.add(speedInMPH!); detectFastSpeedWithAlert(speedInMPH); }, // 增加异常捕获,避免流异常导致功能崩溃 onError: (e) { print("位置监听异常:$e"); } ); }
可选优化
如果你的应用支持用户在设置页手动开关位置权限,可以在当前页面的 didChangeAppLifecycleState 生命周期中监听应用从后台切回前台的事件,重新校验权限并启动监听,覆盖用户手动改权限的场景。
内容的提问来源于stack exchange,提问作者Rash
相关产品推荐
相关产品推荐

