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
相关产品推荐
相关产品推荐

