Flutter使用light 3.0.1包获取环境光单值失败:持续输出无法停止
问题:调用ImagePicker后无法停止环境光传感器的持续输出
我在调用ImagePicker获取图片后,使用light 3.0.1包获取环境光传感器的单次数值,但即便调用了.stopListening()函数,程序仍持续打印lux值,无法停止。
调用代码
final light = AmbientLightDetector(); light.startListening(); final image = await ImagePicker().pickImage(source: option); int luxValue = int.parse(light.luxString); light.stopListening(); logger.i(luxValue);
AmbientLightDetector类实现
class AmbientLightDetector { final logger = Logger(); String luxString = ''; Light? light; StreamSubscription? subscription; void startListening() { light = Light(); try { subscription = light?.lightSensorStream.listen(onData); } on LightException catch (e) { logger.e(e); } } int onData(int luxValue) { logger.i(luxValue); return luxValue; } void stopListening() { subscription?.cancel(); } }
我曾尝试用Duration延迟获取数值,但程序还是持续打印lux值:
light.startListening(); final image = await ImagePicker().pickImage(source: option); int luxValue = await Future.delayed( const Duration(seconds: 1), () { // 等待1秒后获取当前lux值 return int.parse(light.luxString); }, ); light.stopListening();
解决方案
问题核心在于:现有代码未在获取单次数值后立即终止传感器监听,且luxString从未被正确更新。以下是具体调整方案:
1. 重构AmbientLightDetector类
添加专门的单次数值获取方法,获取到第一个数据后自动取消订阅,避免持续输出:
class AmbientLightDetector { final logger = Logger(); String luxString = ''; Light? light; StreamSubscription? subscription; // 获取单次环境光数值,完成后自动停止监听 Future<int> getSingleLuxValue() async { light = Light(); final completer = Completer<int>(); try { subscription = light?.lightSensorStream.listen((luxValue) { logger.i(luxValue); luxString = luxValue.toString(); // 获取到第一个数值后立即终止订阅 subscription?.cancel(); subscription = null; // 清空引用避免内存泄漏 completer.complete(luxValue); }); } on LightException catch (e) { logger.e(e); completer.completeError(e); } return completer.future; } // 手动停止监听的兜底方法 void stopListening() { subscription?.cancel(); subscription = null; } }
2. 修改调用逻辑
直接使用新方法获取单次数值,无需手动管理start/stop:
final lightDetector = AmbientLightDetector(); final image = await ImagePicker().pickImage(source: option); // 自动获取单次lux值并停止监听 int luxValue = await lightDetector.getSingleLuxValue(); logger.i(luxValue); // 可选:兜底调用,确保监听完全终止 lightDetector.stopListening();
关键说明
- 用
Completer将传感器的Stream流转换为Future,实现异步获取单次数值。 - 监听到第一个数值后立即取消订阅,彻底终止传感器的持续输出。
- 清空
subscription引用,避免内存泄漏和重复取消的潜在问题。
内容的提问来源于stack exchange,提问作者G THARUN KUMAR
相关产品推荐
相关产品推荐

