You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

flutter_reactive_ble蓝牙扫描无法停止问题求助

问题解决方案

你的问题根源是每次触发扫描时都创建了新的蓝牙扫描流订阅,但未取消之前的订阅,导致多个扫描任务同时运行,引发冲突报错。以下是具体修复方案:

核心修复步骤

  1. 启动新扫描前,先取消已存在的扫描订阅
  2. 刷新时清空设备列表,避免重复添加
  3. 页面销毁时取消订阅,防止内存泄漏

修改后的代码示例

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:15:29