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

Flutter桌面应用连续运行超24小时后停止页面切换求助

Flutter桌面应用长期运行后页面切换失效问题

我开发了一款简单的Flutter桌面应用,包含图片和视频播放器功能,通过页面导航逐个展示本地asset文件夹中的资源,遍历存储文件名及文件类型(isImage: true/false)的assetslist[]数组。应用运行24小时内一切正常,但超过24小时后会停止循环遍历列表,不再切换页面,屏幕冻结在当前内容上。

原本用来实现页面跳转的代码:

Future.delayed(Duration(seconds: 4), (){
  Navigator.pushReplacement(
    context,
    PageTransition(
      duration: Duration(milliseconds: 100),
      type: PageTransitionType.fade,
      child:(assetslist[currentIndex].isImage)?
      DisplayImagePage(currentIndex:currentIndex):
      DartVclPlayer(currentIndex: currentIndex),
    ),
  );
});

所有资源、索引及文件类型均无问题,尝试改用MaterialPageRoute后,问题依然存在:

Future.delayed(Duration(seconds: 4), () {
  Navigator.pushReplacement(
      context,
      MaterialPageRoute(
        builder: (context) => (assetslist[currentIndex].isImage)
            ? DisplayImagePage(currentIndex: currentIndex)
            : DartVclPlayer(
                currentIndex: currentIndex,
      ));
});

可能的原因及解决办法

1. 延迟任务累积导致队列阻塞

连续嵌套使用Future.delayed触发页面跳转,长期运行后会在Dart事件队列中堆积大量延迟任务,一旦出现未捕获的异步异常,就会导致整个队列停滞,页面切换中断。

解决办法:改用Timer.periodic定时调度
用周期定时器替代单次延迟任务,避免任务堆积,同时保证定时逻辑的稳定性:

late Timer _pageSwitchTimer;

@override
void initState() {
  super.initState();
  // 初始化4秒周期的定时器
  _pageSwitchTimer = Timer.periodic(Duration(seconds: 4), (timer) {
    // 更新索引,循环遍历列表
    currentIndex = (currentIndex + 1) % assetslist.length;
    // 执行页面跳转
    if (mounted) {
      Navigator.pushReplacement(
        context,
        PageTransition(
          duration: Duration(milliseconds: 100),
          type: PageTransitionType.fade,
          child: assetslist[currentIndex].isImage
              ? DisplayImagePage(currentIndex: currentIndex)
              : DartVclPlayer(currentIndex: currentIndex),
        ),
      );
    }
  });
}

@override
void dispose() {
  _pageSwitchTimer.cancel(); // 页面销毁时务必取消定时器
  super.dispose();
}

2. 资源未释放导致内存泄漏

长期运行中,图片缓存、视频播放器资源未正确释放,会导致内存占用持续升高,最终阻塞UI线程或异步任务执行。

解决办法:在页面销毁时清理资源

  • 在DisplayImagePage中清理图片缓存:
@override
void dispose() {
  ImageCache.instance.clear();
  ImageCache.instance.clearLiveImages();
  super.dispose();
}
  • 在DartVclPlayer中停止并销毁播放器:
@override
void dispose() {
  // 根据播放器实际API调用停止、销毁方法
  player.stop();
  player.dispose();
  super.dispose();
}

3. 上下文失效导致导航失败

长期运行过程中,原页面的context可能因组件重建、状态变化等原因失效,导致Navigator.pushReplacement无法执行。

解决办法:增加挂载状态检查
在执行导航操作前,先判断组件是否处于挂载状态:

_timer = Timer.periodic(Duration(seconds: 4), (timer) {
  if (!mounted) {
    timer.cancel();
    return;
  }
  // 执行索引更新和页面跳转逻辑
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:33:14