如何让Flutter中notifyRead的Future等待流接收完17条数据?
解决方案:让notifyRead等待蓝牙流收集完17条数据
要让notifyRead方法等待流收集完17条数据再结束,你可以用Completer将流的完成事件转换成Future,这样外层就能await这个Future,从而实现加载状态的控制。以下是修改后的完整代码:
import 'dart:async'; // 需要引入Completer所在的库 Future notifyRead(Guid characteristic, BuildContext context) async { try { if (await FlutterBlue.instance.isOn) { BluetoothCharacteristic charToTarget = _characteristics .firstWhere((element) => element.uuid == characteristic); await charToTarget.setNotifyValue(true); clearInfo(); // 创建Completer,用来标记流的完成 final completer = Completer<void>(); late StreamSubscription<List<int>> streamSubscription; streamSubscription = charToTarget.value.listen( (value) { var temp = String.fromCharCodes(value); _info.add(temp); print(temp); notifyListeners(); if (temp.startsWith("batt")) { updateBattValues(temp); } updateWifiVerificationStatus(); if (_info.length == 17) { log("Finished Sending Data "); _notifyFinished = true; notifyListeners(); // 完成completer,取消流订阅 completer.complete(); streamSubscription.cancel(); return; } }, // 处理流异常,避免Future一直挂起 onError: (error) { log("Stream error: ${error.toString()}"); completer.completeError(error); streamSubscription.cancel(); }, // 流意外结束时也完成completer onDone: () { if (!completer.isCompleted) { completer.complete(); } }, ); await charToTarget.write(INFO.codeUnits); // 等待流完成 await completer.future; } else { Fluttertoast.showToast(msg: "蓝牙似乎已关闭"); } } catch (e) { log("获取信息时出错:${e.toString()}"); Fluttertoast.showToast( msg: "获取信息时出错:${e.toString()}"); } }
关键修改说明:
- Completer的使用:通过
Completer将流的完成状态转换成Future,让notifyRead可以等待这个Future完成 - 流订阅管理:用
late StreamSubscription保存订阅对象,在数据收集完成或出错时取消订阅,避免内存泄漏 - 异常处理:监听流的
onError事件,出错时完成completer并传递错误,防止Future一直处于等待状态 - 流意外结束处理:监听
onDone事件,确保即使流提前结束,completer也能完成,避免方法挂起
加载状态控制:
在按钮点击时,你可以这样控制加载状态:
bool isLoading = false; // 按钮onTap回调 void onTapNotifyRead() async { setState(() { isLoading = true; }); try { await notifyRead(yourCharacteristicGuid, context); } finally { setState(() { isLoading = false; }); } }
然后在UI中根据isLoading显示加载组件(比如CircularProgressIndicator)。
内容的提问来源于stack exchange,提问作者Eashubh Thapliyal
相关产品推荐
相关产品推荐

