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

Flutter Android端Camera插件多次跳转后报Session已关闭错误如何解决?

崩溃根因

报错java.lang.IllegalStateException: Session has been closed; further changes are illegal.是因为相机捕获会话已经被系统/插件释放后,仍有异步回调尝试操作会话对象,触发非法状态异常。你每次进出页面都存在少量相机资源未完全释放的问题,累计到10次左右达到系统相机实例上限,就会必然崩溃,核心问题出在异步操作时序和资源释放逻辑的漏洞,以及你使用的0.9.4版本camera插件本身存在已知的资源释放bug。

修复方案
  • 首先修复跳页前的资源预释放逻辑
    你当前检测到驾照条码后直接执行跳页,此时相机图像流仍在运行,帧处理异步任务还在排队,跳页触发的dispose释放资源和后台回调操作出现时序冲突,需要在跳页前先暂停所有相机操作:
    if (bcode.type == BarcodeType.driverLicense) {
      BarcodeDriverLicense bcodeDL = bcode.value as BarcodeDriverLicense;
      String scannedName = bcodeDL.lastName! + ", " + bcodeDL.firstName!;
      // 新增:永久锁定帧处理,停止所有相机操作
      isBusy = true;
      await _controller?.stopImageStream();
      await _controller?.dispose();
      _controller = null;
      // 新增:判断页面是否还存在再跳页
      if (mounted) {
        Navigator.of(context).popAndPushNamed(
            AnotherScreen.ANOTHER_SCREEN_ROUTE,
            arguments: ScannedInfoArguments(scannedName));
      }
      break;
    }
    
  • 补充页面销毁标记,拦截无效异步回调
    dispose方法是同步执行的,你当前没有等待相机资源释放完成就销毁页面,很多异步回调会在页面销毁后才执行,需要加标记拦截无效操作:
    1. 新增状态属性bool _isDisposed = false;
    2. 重写dispose方法:
    @override
    void dispose() {
      _isDisposed = true;
      _stopLiveFeed();
      barcodeScanner.close();
      super.dispose();
    }
    
    1. 所有涉及_controller操作的位置都要加状态校验,比如帧处理入口:
    Future _processCreateInputImage(CameraImage image) async {
      // 新增:页面已销毁/控制器未初始化直接返回
      if (isBusy || _isDisposed || _controller == null || !_controller!.value.isInitialized) return;
      isBusy = true;
      // 原有逻辑不变
    }
    
    还有控制器初始化回调也要加校验:
    _controller?.initialize().then((_) {
      if (!mounted || _isDisposed || _controller == null) {
        return;
      }
      _controller?.startImageStream(_processCreateInputImage);
      if (mounted) setState(() {});
    });
    
  • 修复_stopLiveFeed的空安全逻辑
    给_stopLiveFeed方法加空判断和异常捕获,避免操作已经释放的控制器:
    Future _stopLiveFeed() async {
      if (_controller != null) {
        try {
          await _controller?.stopImageStream();
          await _controller?.dispose();
        } catch (e) {
          // 忽略释放阶段的非法状态异常
        }
        _controller = null;
      }
    }
    
  • 升级camera插件版本
    你使用的0.9.4版本camera插件存在大量Android端Camera2会话管理的已知bug,可升级到camera: ^0.10.0+1,该版本官方修复了会话关闭后调用方法的崩溃问题。如果Flutter 2.5.1版本无法兼容高版本插件,可以在Android层的相机回调代码中手动捕获IllegalStateException异常规避崩溃。
  • 优化相机初始化逻辑
    每次执行_startLiveFeed前先调用一次_stopLiveFeed,确保上一次的相机资源已经完全释放,再初始化新的控制器实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:00:00