flutter_reactive_ble蓝牙扫描无法停止问题求助
问题解决方案
你的问题根源是每次触发扫描时都创建了新的蓝牙扫描流订阅,但未取消之前的订阅,导致多个扫描任务同时运行,引发冲突报错。以下是具体修复方案:
核心修复步骤
- 启动新扫描前,先取消已存在的扫描订阅
- 刷新时清空设备列表,避免重复添加
- 页面销毁时取消订阅,防止内存泄漏
修改后的代码示例
1. 类成员变量声明
确保scanStream是类级别的可空订阅对象:
StreamSubscription? scanStream; List<DeviceModel> devices = []; // 你的设备列表
2. 刷新方法修改
在启动新扫描前先停止旧扫描:
Future<void> refresh() async { // 取消当前活跃的扫描订阅 await scanStream?.cancel(); // 清空设备列表,保证刷新后显示最新扫描结果 setState(() => devices.clear()); // 启动新扫描 searchingDevice(); }
3. 扫描方法优化
保持原有逻辑,确保订阅对象正确赋值:
void searchingDevice() { print('searching device'); try { scanStream = flutterReactiveBle.scanForDevices( withServices: [], scanMode: ScanMode.lowLatency ).listen((device) { if (device.name.isNotEmpty) { _addDeviceTolist(device.id, device.name); } }, onError: (e) { print(e.toString()); // 自定义错误处理 }); } catch (e) { showDialog( context: context, builder: (_) => AlertDialog( title: const Text('警告'), content: Text(e.toString()), ), ); } }
4. 设备添加去重(可选但建议)
避免同一设备多次添加到列表:
void _addDeviceTolist(String id, String name) { bool isDeviceExist = devices.any((device) => device.id == id); if (!isDeviceExist) { setState(() { devices.add(DeviceModel(id: id, deviceName: name)); }); } }
5. 页面销毁时清理订阅
防止后台持续扫描导致内存泄漏:
@override void dispose() { scanStream?.cancel(); super.dispose(); }
修复说明
- 取消旧订阅后再启动新扫描,彻底避免多任务冲突
- 清空设备列表保证每次刷新都是最新的扫描结果
dispose时清理订阅,避免页面销毁后后台仍在执行扫描操作
内容的提问来源于stack exchange,提问作者Lanlan Sun
相关产品推荐
相关产品推荐

