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

Flutter使用Camera组件报LateError:_controller未初始化如何解决?

问题根因

你的代码存在多个语法和逻辑错误共同触发了LateError,核心问题是对late关键字的使用错误、变量作用域冲突、异步逻辑处理不当:

    1. initState中声明了同名局部变量CameraController _controller;,完全覆盖了类成员变量,这行代码完全没有给类的_controller赋值,属于无用代码。
    1. 用late修饰的_controller不允许判断== null,late关键字的语义是你承诺在第一次访问前必然完成初始化,如果你需要判断是否初始化,应该将变量声明为可空类型CameraController? _controller;
    1. setupCamera是异步方法,initState中调用它不会等待执行完成,组件首次执行build时_controller还未完成初始化,直接访问就会触发LateError
    1. dispose方法中错误调用了addObserver,应该调用removeObserver移除生命周期监听,否则会导致内存泄漏和废弃回调触发
    1. didChangeAppLifecycleState中判断_controller == null的逻辑本身就会触发未初始化的LateError,同时dispose控制器后没有重置状态,下次访问也会报错

解决方案

按以下步骤修改代码即可解决问题:

第一步:调整变量声明

将late修饰的变量改为可空类型,符合需要判断是否初始化的使用场景:

// 替换原来的late声明
List<CameraDescription>? _cameras;
CameraController? _controller;
int _selected = 0;

第二步:修正initState中的无用代码

删掉initState里的局部变量声明:

@override
void initState() {
  super.initState();
  setupCamera();
  WidgetsBinding.instance.addObserver(this);
}

第三步:修正dispose方法的监听移除逻辑

@override
void dispose() {
  WidgetsBinding.instance.removeObserver(this);
  _controller?.dispose();
  super.dispose();
}

第四步:修正生命周期回调的判断逻辑

@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
  final controller = _controller;
  if (controller == null || !controller.value.isInitialized) {
    return;
  }

  if (state == AppLifecycleState.inactive) {
    controller.dispose();
    setState(() {
      _controller = null;
    });
  } else if (state == AppLifecycleState.resumed) {
    setupCamera();
  }
}

第五步:完善build方法的判空逻辑

@override
Widget build(BuildContext context) {
  final controller = _controller;
  if (controller == null || !controller.value.isInitialized) {
    return widget.loadingWidget ?? Container(color: Colors.black);
  } else {
    return CameraPreview(controller);
  }
}

第六步:完善相机初始化逻辑的空安全处理

Future<void> setupCamera() async {
  await [Permission.camera].request();
  _cameras = await availableCameras();
  if (_cameras?.isEmpty ?? true) return;
  final controller = await selectCamera();
  setState(() => _controller = controller);
}

Future<CameraController> selectCamera() async {
  var controller = CameraController(_cameras![_selected], ResolutionPreset.max);
  await controller.initialize();
  return controller;
}

Future<void> toggleCamera() async {
  final cameras = _cameras;
  if (cameras == null || cameras.isEmpty) return;
  int newSelected = (_selected + 1) % cameras.length;
  _selected = newSelected;
  _controller?.dispose();
  final controller = await selectCamera();
  setState(() => _controller = controller);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:36:03