如何解决Flutter中的LateInitializationError?

amrnrhlw  于 2023-10-22  发布在  Flutter
关注(0)|答案(4)|浏览(484)

我遇到了以下问题,希望有人能帮助我。我尝试使用以下代码将相机包含在我的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()方法,并使用了?”但它也没有工作。
有人有主意吗?

t40tm48m

t40tm48m1#

我认为问题是你正在运行'setupCameras()',它在'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)
        );
      };
    );
  }
}
7z5jn7bk

7z5jn7bk2#

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

  • 我不认为FutureBuilder在这种情况下会起作用。你还得处理掉。这似乎不是你使用FutureBuilder可以做到的。
  • 实际情况是,您可能无法成功初始化CameraController。无论出于何种原因,getCameras都不会返回任何内容。这意味着您的CameraController始终可能为null。因此,试图调整代码以强制此类型为非空类型是不正确的。

最后我把它改成了可空类型,并在必要的时候进行空检查。国际海事组织, dart 是去远为零安全。只会让事情变得更复杂。我喜欢Python使用None处理nullable的方式。

CameraController? _controller;
yrwegjxp

yrwegjxp3#

我看到两个问题:

  1. setupCameras()可以:
try {
  // ...
} on CameraException catch () {
  setState(() {
    isReady = false;
  });
}
setState(() {
  isReady = true;
});

这意味着如果抛出CameraExceptionisReady将被设置为false,但随后立即被设置为true

  1. build函数:
if (!isReady && !_controller.value.isInitialized) {
  return Container();
}

如果isReady为false(我假设 * 应该 * 表示_controller尚未初始化),那么即使_controller尚未初始化,也要检查_controller.value.isInitialized。您可能需要||而不是&&
或者,考虑只将_controller设为空,而不是late。如果您需要在访问_controller之前检查布尔标志(isReady),这并不比将_controller设置为空并直接检查_controller != null更好,这更直接,更不容易出错。

m4pnthwp

m4pnthwp4#

错误“LateInitializationError:代码中的“字段”控制器“尚未初始化”与未正确初始化_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方法,以便在释放控件时正确地释放相机控制器。

相关问题