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

Flutter弹窗异常求助:多次触发后叠加显示历史弹窗

Flutter弹窗重复叠加问题解决方案

问题根源

你遇到的弹窗叠加问题,核心原因是USB事件流被重复订阅。每次调用InitConnection()时,都会新增一个USB事件监听器,但之前的监听器没有被取消,导致多个监听器同时存在。当USB断开事件触发时,所有活跃的监听器都会调用弹窗方法,最终出现“第N次触发显示前N个弹窗”的叠加现象。

结合你提供的代码来看,InitConnection()是每15秒定时执行的,这会导致每次定时触发都新增一个监听器,叠加次数随执行次数递增,完全匹配你描述的异常表现。

修复步骤

1. 订阅前清理旧监听器

在创建新的USB事件监听器前,先取消之前的订阅:

// Listen for a detached USB cable
// 先取消旧的订阅,避免重复监听
await usbListener?.cancel();
usbListener = UsbSerial.usbEventStream?.listen((UsbEvent msg) {
  print(msg);
  if (msg.event == UsbEvent.ACTION_USB_ATTACHED) {
    print("USB CONNECTED");
  }
  if (msg.event == UsbEvent.ACTION_USB_DETACHED) {
    ErrorMessage(context, "Lost connection");
    setState(() {
      connectionStatus = false;
      listenWait = false;
      listenEnabled = false;
      usbConnected = false;
    });
    try {
      iTimer.cancel();
    } catch(e) {
      print(e);
    }
    ResetFields();
  }
});

2. 页面销毁时清理资源

在页面销毁的生命周期方法中,彻底取消监听器和定时器,避免内存泄漏:

@override
void dispose() {
  usbListener?.cancel();
  iTimer?.cancel();
  super.dispose();
}

3. 定时逻辑去重

创建新定时器前,先取消旧的定时器,避免重复触发InitConnection():

void InitConnection() async {
  print("*** INIT CONNECTION RUNNING...");
  // 先取消旧定时器,防止重复执行
  iTimer?.cancel();
  setState(() {
    initLoading = true;
    connectionStatus = false;
    usbConnected = true;
  });
  iTimer = Timer(Duration(milliseconds: 10000), InitGuarantor);
  // ... 剩余原有代码保持不变
}

验证说明

修改后,每次执行InitConnection()都会先清理旧的监听器和定时器,确保始终只有一个监听器监听USB事件,USB断开时只会触发一次弹窗,不会再出现叠加问题。你测试的多款弹窗插件和原生弹窗都出现相同问题,也说明问题不在弹窗组件本身,而是触发弹窗的逻辑被多次执行导致的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:15:38