如何解决Flutter中的LateInitializationError?

问题描述 投票:0回答:4

大家好,我遇到以下问题,希望有人可以帮助我: 我尝试使用以下代码将相机包含在我的 flutter 应用程序中:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';


class Route02 extends StatefulWidget {
  @override
  CameraState createState() => CameraState();
}

class CameraState extends State<Route02> {
  late List<CameraDescription> cameras;
  late CameraController _controller;
  bool isReady = false;

  @override
  void initState() {
    super.initState();
    setupCameras();
  }

  Future<void> setupCameras() async {
    try {
      cameras = await availableCameras();
      _controller = new CameraController(cameras[0], ResolutionPreset.ultraHigh);
      await _controller.initialize();
    } on CameraException catch () {
      setState(() {
        isReady = false;
      });
    }
    setState(() {
      isReady = true;
    });
  }

  Widget build(BuildContext context) {
    if (!isReady && !_controller.value.isInitialized) {
      return Container();
    }
    return AspectRatio(
        aspectRatio: _controller.value.aspectRatio,
        child: CameraPreview(_controller));
  }
}

在应用程序内访问相机部分时,可以看到以下错误,然后相机仍会启动:

LateInitializationError:字段“控制器”尚未初始化。

我已经尝试添加 whenComplete() 方法并使用了 ? 但它也不起作用。

有人有想法吗?

flutter dart exception error-handling solution
4个回答
4
投票

我认为问题在于您正在运行“setupCameras()”,它在“initState()”方法中是异步的,而“initState()”方法不是。试试这个:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';


class Route02 extends StatefulWidget {
  @override
  CameraState createState() => CameraState();
}

class CameraState extends State<Route02> {
  late List<CameraDescription> cameras;
  late CameraController _controller;


  Future<void> setupCameras() async {
    try {
      cameras = await availableCameras();
      _controller = new CameraController(cameras[0], ResolutionPreset.ultraHigh);
      await controller.initialize();
  }

  Widget build(BuildContext context) {
    return FutureBuilder(
      future: setupCameras(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        return AspectRatio(
          aspectRatio: _controller.value.aspectRatio,
          child: CameraPreview(_controller)
        );
      };
    );
  }
}

1
投票

我也遇到同样的问题,找不到完美的解决方案。

  • 我认为 FutureBuilder 在这种情况下不起作用。您还需要处理处置。这似乎不是您使用 FutureBuilder 可以做到的。

  • 现实情况是,你可能无法成功初始化CameraController。无论出于何种原因, getCameras 都不会返回任何内容。这意味着您的 CameraController 始终有可能为 null。因此,尝试调整代码以强制其为非空类型是不正确的。

我最终只是将其更改为可空类型,并在必要时进行空检查。在我看来,dart 在零安全性方面已经走得太远了。它只会让事情变得更加复杂。我喜欢 Python 使用 None 处理可为空的方式。

CameraController? _controller;

0
投票

我看到两个问题:

  1. setupCameras()
    确实:

    try {
      // ...
    } on CameraException catch () {
      setState(() {
        isReady = false;
      });
    }
    setState(() {
      isReady = true;
    });
    

    这意味着如果抛出

    CameraException
    isReady
    将被设置为
    false
    ,但随后立即被设置为
    true

  2. build
    函数的作用是:

    if (!isReady && !_controller.value.isInitialized) {
      return Container();
    }
    

    如果

    isReady
    为 false(我认为 should 表明
    _controller
    尚未初始化),那么即使
    _controller.value.isInitialized
    尚未初始化,您还要检查
    _controller
    。您可能想要
    ||
    而不是
    &&

或者,考虑仅将

_controller
设置为空,而不是
late
。如果您需要在访问
isReady
之前检查布尔标志 (
_controller
),这并不比使
_controller
可为空并直接检查
_controller != null
更好,这样更直接且更不容易出错。


0
投票

代码中的错误“LateInitializationError:字段'controller'尚未初始化”与_controller变量未正确初始化有关。看来您正在尝试在 initState 方法中初始化 _controller 之前使用它。您应该仅在初始化后访问 _controller。这是代码的修改版本,以确保正确初始化:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera';

class Route02 extends StatefulWidget {
  @override
  CameraState createState() => CameraState();
}

class CameraState extends State<Route02> {
  late List<CameraDescription> cameras;
  late CameraController _controller;
  bool isReady = false;

  @override
  void initState() {
    super.initState();
    setupCameras();
  }

  Future<void> setupCameras() async {
    try {
      cameras = await availableCameras();
      _controller = CameraController(cameras[0], ResolutionPreset.ultraHigh);

      // Ensure that the widget is mounted before initializing the controller
      if (!mounted) {
        return;
      }

      await _controller.initialize();
      setState(() {
        isReady = true;
      });
    } on CameraException catch (e) {
      print("Error: $e");
      setState(() {
        isReady = false;
      });
    }
  }

  @override
  void dispose() {
    _controller.dispose(); // Don't forget to dispose of the controller.
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (!isReady || !_controller.value.isInitialized) {
      return Container();
    }
    return AspectRatio(
        aspectRatio: _controller.value.aspectRatio,
        child: CameraPreview(_controller),
    );
  }
}

注意:在初始化之前检查小部件是否仍然挂载 相机控制器以避免错误。还添加了一个 dispose 方法 处理小部件时正确处理相机控制器。

© www.soinside.com 2019 - 2024. All rights reserved.