You need to enable JavaScript to run this app. Flutter异步发送MIDI SysEx消息时UI冻结、进度条不显示如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Flutter异步发送MIDI SysEx消息时UI冻结、进度条不显示如何解决

问题原因

1. 同步阻塞导致UI无法刷新

你调用了dart:io库的sleep()方法,这是同步阻塞函数,会直接卡住Flutter主UI线程的事件循环。即便send方法声明为异步,sleep本身不会让出执行权,你调用setState后UI要等所有sleep执行完毕才会批量渲染,自然看不到进度更新。

2. 进度值范围不匹配

LinearProgressIndicator的value属性要求传入0~1区间的浮点数,你当前计算逻辑_progress = 100/chunks*chunkCount得到的是0~100的数值,超过1之后进度条会一直显示满格状态,看不到变化。

修复方案

  1. 把同步的sleep替换为异步等待Future.delayed,不会阻塞UI线程,同时给Flutter留出渲染UI的时间
  2. 调整进度计算逻辑,将值缩放到0~1区间
  3. 可选优化:如果sendData方法是异步的,建议增加await调用,确保上一块数据发送完成再处理下一块,避免MIDI消息丢包

修复后的send方法代码:

Future<void> send(Uint8List _syxData) async {
  _midiCommand.connectToDevice(oxiOne.OxiOne().device);

  int chunkSize = _syxData.indexWhere((element) => element == 0xf7) + 1;
  int chunks = (_syxData.lengthInBytes % chunkSize == 0) ?
  _syxData.lengthInBytes ~/ chunkSize :
  _syxData.lengthInBytes ~/ chunkSize + 1;

  for (int chunkCount = 1, start = 0, end = chunkSize; chunkCount <= chunks; chunkCount++ ){
    if (chunkCount == chunks){
      dev.log("sending last chunk: ");
      // 如果sendData是异步方法,建议加await
      await _midiCommand.sendData(_syxData.sublist(start));
    } else {
      dev.log("last byte of this chunk $chunkCount is ${_syxData[end-1]}");
      await _midiCommand.sendData(_syxData.sublist(start, end));
    }
    start = chunkCount*chunkSize;
    end = start+chunkSize;
    // 替换同步sleep为异步等待
    await Future.delayed(const Duration(milliseconds: 190));
    if (chunkCount == chunks) {
      return;
    } else {
      setState(() {
        // 调整进度值到0~1区间
        _progress = chunkCount / chunks;
      });
    }
  }
}

内容的提问来源于stack exchange,提问作者Noir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 17:21:00