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

Flutter showModalBottomSheet选图后调用setState报dispose错误如何解决

根本原因

  • 你对报错对象的判断有误:异常堆栈明确显示报错的是父页面_RegisterIDPhotosState的state,不是showModalBottomSheet的state。BottomSheet销毁本身不会影响父页面的state调用setState。
  • 触发报错的核心场景:唤起系统相机/图库时,App退至后台,若系统内存不足,会回收后台的_RegisterIDPhotosState对应页面,等你选完图回到App时,原State实例已经被标记为defunct、mounted为false,此时异步回调执行到setState就会抛出异常。
  • 你仅加mounted判断不符合预期的原因是:如果页面真的被系统回收,就算跳过setState,上传任务仍在后台运行,状态无法同步到重建后的新页面实例上。

解决方案

1. 基础可靠修复(适配绝大多数场景)

在每个setState前加mounted判断的同时,对上传异步任务做取消处理,避免内存泄漏和无效回调执行:

import 'package:async/async.dart';

// 声明可取消的上传任务
CancelableOperation? _uploadOperation;

Future<void> _handleFile(XFile? xfile, int orientation) async {
  if (xfile == null) return;
  // 进入方法先判断页面是否存活
  if (!mounted) return;

  var imageService = locator<ImageService>();
  setState(() {
    remoteImageStatus[xfile] = UploadStatus.Uploading;
    images[orientation] = xfile;
  });

  // 用CancelableOperation包装上传任务
  _uploadOperation = CancelableOperation.fromFuture(
    imageService.uploadIDPhoto(File(xfile.path), orientation)
  );

  try {
    final value = await _uploadOperation?.value;
    // 上传完成后先判断页面是否存活再更新状态
    if (mounted) {
      setState(() {
        idPhotos[orientation] = value;
        remoteImageStatus[xfile] = UploadStatus.Done;
      });
    }
    print("Uploaded [${xfile.path}]");
  } catch (error, stackTrace) {
    // 任务被主动取消的情况直接返回
    if (error is CanceledException) return;
    print("Error uploading image");
    print(stackTrace);
    if (mounted) {
      setState(() {
        remoteImageStatus[xfile] = UploadStatus.Error;
      });
    }
  }
}

@override
void dispose() {
  // 页面销毁时主动取消未完成的上传任务
  _uploadOperation?.cancel();
  super.dispose();
}

2. 状态持久化修复(解决系统回收页面后状态丢失问题)

如果需要在页面被系统回收重建后仍能同步上传状态,建议将上传逻辑和状态从页面层剥离,放到全局业务层管理:

  • 基于你已经接入的get_it容器,可以给ImageService扩展上传状态流的监听能力,把每个文件的上传进度、状态存在Service层
  • 页面只需要监听Service层的状态流,重建后重新监听就能拿到最新的上传状态,无需依赖页面本身的state存储上传相关数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:15:00