Flutter_blue读取蓝牙特征值出现read_characteristic_error异常求助
异常触发原因
- 核心原因是Dart中
forEach方法不会等待异步回调执行完成:你传入的async回调会被并发触发,导致多个蓝牙特征值的read操作同时发起。蓝牙协议不支持同一时间并行执行多个读写请求,上一个读操作未完成就发起下一个,就会抛出该异常。 - 代码存在作用域错误:
write方法调用时的变量c是特征值循环内的局部变量,循环结束后在外部调用会拿到非法对象,进一步打乱读写时序。 - 未做特征值属性校验:部分蓝牙特征值本身不支持读操作,强行调用
read方法也会触发同类异常。
修复方案
修复后参考代码
// 设备连接 final device_connection = await r.device.connect(); // 发现服务 List<BluetoothService> services = await r.device.discoverServices(); // 使用普通for循环替代forEach,保证异步操作串行执行 for (var service in services) { var characteristics = service.characteristics; for (BluetoothCharacteristic c in characteristics) { // 先校验特征值是否支持读操作 if (c.properties.read) { List<int> value = await c.read(); print(value); } // 写操作放在循环内,校验写权限后执行 if (c.properties.write) { await c.write([0x12, 0x34]); } } }
核心修改点
- 替换
forEach为普通for循环:普通for循环会等待await标记的异步操作执行完成后再进入下一轮循环,保证所有蓝牙读写操作串行执行,避免并行请求冲突。 - 增加特征值属性校验:读写操作前先判断
properties中对应权限是否开启,避免非法调用。 - 修正
write方法的调用位置:将写操作移入特征值遍历循环内,保证操作的是当前合法的特征值对象,避免作用域错误。 - 可选优化:可给单个读写操作增加
try-catch捕获异常,避免单个特征值操作失败导致整个流程中断,也可增加超时逻辑避免长时间阻塞。
内容的提问来源于stack exchange,提问作者Syed Ahad
相关产品推荐
相关产品推荐

