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

如何让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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:43:17