Flutter中forEach嵌套for循环实现蓝牙分包发送异常排查
问题分析与修复方案
代码核心问题
- 异步操作未等待:
c.read()是异步方法,但原代码未加await,导致发送数据包后没等收到通知就执行后续逻辑,无法触发自动发送下一个包。 - 循环逻辑混乱:
- 外层
Future.forEach本应遍历所有chunk,但内部嵌套的固定次数循环(i<1、i<247)完全打乱顺序,重复发送同一个chunk,没有按拆分后的顺序逐个发送。 - 硬编码循环次数(247),没有根据实际拆分的chunk数量动态处理,通用性极差。
- 外层
- 状态判断逻辑错误:
c.isNotifying的判断位置不对,无法准确实现“收到第一个包通知后再发剩余包”的需求。
修复后的代码示例
// 确保chunks列表不为空再执行 if (chunks.isNotEmpty) { // 发送第一个数据包并等待通知 await c.write(chunks[0] as List<int>, withoutResponse: false); await c.read(); // 遍历剩余数据包,逐个发送并等待通知 for (int i = 1; i < chunks.length; i++) { final currentChunk = chunks[i]; await c.write(currentChunk as List<int>, withoutResponse: false); await c.read(); // 若设备需要间隔,可保留延迟,但建议根据通知时机调整,而非固定时长 // await Future.delayed(const Duration(milliseconds: 300)); } }
关键修复点说明
- 明确区分首个数据包和剩余数据包的发送流程,先完成第一个包的发送与通知接收,再逐个处理后续包。
- 所有异步操作(
c.write、c.read)均添加await,确保执行顺序严格按预期进行,前一步完成后再触发下一步。 - 移除硬编码循环次数,改用
chunks.length动态控制,适配不同大小的文件拆分结果。 - 将
withoutResponse设为false:因为需要设备返回成功通知,可靠传输模式更符合需求(原代码用true可能导致设备不返回通知)。
内容的提问来源于stack exchange,提问作者AMAL
相关产品推荐
相关产品推荐

