Home > Enterprise >  How do I solve split second Flutter Late Initialization Camera Error in async function?
How do I solve split second Flutter Late Initialization Camera Error in async function?

Time:01-06

I'm working on a web app that includes taking pictures. The camera works, and automatically loads when the user moves to the camera page. the only issue is that for about half a second, the screen flashes red with a "LateInitializationError: Field 'camController' has not been initialized" error (camController being my camera controller).

Here is my screen code:

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

class createView extends StatefulWidget {
  const createView({Key? key}) : super(key: key);

  @override
  State<createView> createState() => _createViewState();
}

class _createViewState extends State<createView> {
  late List<CameraDescription> deviceCameras;
  late CameraController camController;

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

  void getCamera() async {
    final deviceCameras = await availableCameras();
    camController = CameraController(deviceCameras.first, ResolutionPreset.high,
        enableAudio: false);
    await camController.initialize().then((value) {
      if (!mounted) {
        return;
      }
      setState(() {});
    }).catchError((e) {
      print(e);
    });
  }

  @override
  void dispose() {
    camController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (camController.value.isInitialized) {
      return Scaffold(
        body: Center(
          child: SingleChildScrollView(
            child: Container(
              padding: const EdgeInsets.all(20),
              decoration: BoxDecoration(
                color: Color.fromARGB(136, 255, 255, 255),
                borderRadius: BorderRadius.all(Radius.circular(20)),
                boxShadow: [
                  BoxShadow(
                      color: Color.fromARGB(37, 0, 0, 0),
                      spreadRadius: 1,
                      blurRadius: 15)
                ],
              ),
              width: 300,
              child: CameraPreview(camController),
            ),
          ),
        ),
      );
    } else {
      return CircularProgressIndicator();
    }
  }
}

and my error log:

The following LateError was thrown building createView$(dirty, state: _createViewState#54a24):
LateInitializationError: Field 'camController' has not been initialized.
The relevant error-causing widget was:
createView$
lib\home.dart:19
When the exception was thrown, this was the stack:
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49      throw_
packages/podvus/myViews/createView.dart 13:25                                                                                  get camController
packages/podvus/myViews/createView.dart 43:29                                                                                  build
packages/flutter/src/widgets/framework.dart 4992:27   
packages/flutter/src/widgets/framework.dart 4878:15                                                                            performRebuild
packages/flutter/src/widgets/framework.dart 5050:11                                                                            performRebuild
packages/flutter/src/widgets/framework.dart 4604:5                                                                             rebuild
packages/flutter/src/widgets/framework.dart 4859:5                                                                             [_firstBuild]
packages/flutter/src/widgets/framework.dart 5041:11                                                                            [_firstBuild]
packages/flutter/src/widgets/framework.dart 4853:5                                                                             mount
packages/flutter/src/widgets/framework.dart 3863:15                                                                            inflateWidget 

and so on.

the error is within the building of the screen itself, as removing references to it in the build method removes the error. I'm trying to change the if (camController.value.isInitialized) to something else to make it work.

CodePudding user response:

It is not recommended to use late if it involves any async initialization.

Also there is a possibility that the deviceCameras returned can be empty. So the best way would be to define the camController and the deviceCameras as optional and handle the null values gracefully in the later code.

List<CameraDescription>? deviceCameras;
CameraController? camController;

CodePudding user response:

Found the answer- two lines of code: use a bool value as a trigger that will update to true when camera is actually initialized. use that in the "if (camController.value.isInitialized)" then the app will show the loading indicator while the camera initializes instead of the error.

  class _createViewState extends State<createView> {
  late List<CameraDescription> deviceCameras;
  late CameraController camController;
  bool isReady = false;

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

  void getCamera() async {
    final deviceCameras = await availableCameras();
    camController = CameraController(deviceCameras.first, ResolutionPreset.high,
        enableAudio: false);
    await camController.initialize().then((value) {
      isready = true;
      if (!mounted) {
        return;
      }
      setState(() {});
    }).catchError((e) {
      print(e);
    });
  }

  @override
  void dispose() {
    camController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (isReady) {
      return Scaffold(
  • Related