Repository: flutter
Issue: [camera]  startImageStream - Lifecycle Issues
Labels: platform-android,p: camera,package,has reproducible steps,P2,found in release: 2.5,found in release: 2.6,team-android,triaged-android

Hi, I have an issue with the camera when using startImageStream, but only on some Android devices. There I get the following exceptions (at some time) when switching the lifecycle. 

One device where we can create the issue is the following:
    • SM G986B (mobile) • RFCN20GEW7F • android-arm64  • Android 11 (API 30)

```
E/AndroidRuntime(10657): FATAL EXCEPTION: pool-10-thread-1
E/AndroidRuntime(10657): Process: com.example.camera_test, PID: 10657
E/AndroidRuntime(10657): java.lang.IllegalStateException: Session has been closed; further changes are illegal.
```

```
E/AndroidRuntime(15215): FATAL EXCEPTION: pool-15-thread-1
E/AndroidRuntime(15215): Process: com.example.camera_test, PID: 15215
E/AndroidRuntime(15215): java.lang.IllegalArgumentException: No handler given, and current thread has no looper!
```

Sometimes also the CameraPreview causes an error
```
======== Exception caught by widgets library =======================================================
The following assertion was thrown building CameraPreview:
A CameraController was used after being disposed.

Once you have called dispose() on a CameraController, it can no longer be used.
The relevant error-causing widget was: 
  CameraPreview camera_test/lib/main.dart:104:13
When the exception was thrown, this was the stack: 
#0      ChangeNotifier._debugAssertNotDisposed.<anonymous closure> (package:flutter/src/foundation/change_notifier.dart:117:9)
#1      ChangeNotifier._debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:123:6)
#2      ChangeNotifier.addListener (package:flutter/src/foundation/change_notifier.dart:176:12)
#3      _ValueListenableBuilderState.initState (package:flutter/src/widgets/value_listenable_builder.dart:162:28)
#4      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4711:57)
```

The code is based on the example and just startImageStream is called. As far as I know, with the dispose the image stream is closed as well, so I think there is an issue in the package. On iPhone I could not produce the error.
```
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';

List<CameraDescription>? cameras;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  cameras = await availableCameras();
  runApp(CameraApp());
}

class CameraApp extends StatefulWidget {
  @override
  _CameraAppState createState() => _CameraAppState();
}

class _CameraAppState extends State<CameraApp>
    with WidgetsBindingObserver, TickerProviderStateMixin {
  CameraController? controller;

  @override
  void initState() {
    super.initState();
    controller = CameraController(cameras![0], ResolutionPreset.max);
    _ambiguate(WidgetsBinding.instance)?.addObserver(this);
    controller!.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

  @override
  void dispose() {
    _ambiguate(WidgetsBinding.instance)?.removeObserver(this);
    super.dispose();
  }

  void onNewCameraSelected(CameraDescription cameraDescription) async {
    if (controller != null) {
      await controller!.dispose();
    }

    final CameraController cameraController = CameraController(
      cameraDescription,
      ResolutionPreset.medium,
      enableAudio: true,
    );

    controller = cameraController;

    // If the controller is updated then update the UI.
    cameraController.addListener(() {
      if (mounted) setState(() {});
      if (cameraController.value.hasError) {
        print('Camera error ${cameraController.value.errorDescription}');
      }
    });

    try {
      await cameraController.initialize();
    } on CameraException catch (e) {
      print(e);
    }

    if (mounted) {
      setState(() {});
    }

    await cameraController.startImageStream((image) => onLatestImageAvailable);

  }

  void onLatestImageAvailable(CameraImage cameraImage) {
    print("I am here");
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // App state changed before we got the chance to initialize.
    if (controller == null || !controller!.value.isInitialized) {
      return;
    }
    if (state == AppLifecycleState.inactive) {
      controller?.dispose();
    } else if (state == AppLifecycleState.resumed) {
      if (controller != null) {
        onNewCameraSelected(controller!.description);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    if (!controller!.value.isInitialized) {
      return Container();
    }
    return MaterialApp(
      home: CameraPreview(controller!),
    );
  }
}

T? _ambiguate<T>(T? value) => value;
```

This is a screenshot of the error:


flutter doctor -v
```
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.5.2 20G95 darwin-arm, locale en-AT)
    • Flutter version 2.2.3 at /Users/markusnissl/development/flutter
    • Framework revision f4abaa0735 (3 months ago), 2021-07-01 12:46:11 -0700
    • Engine revision 241c87ad80
    • Dart version 2.13.4

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at /Users/markusnissl/Library/Android/sdk
    • Platform android-30, build-tools 30.0.2
    • ANDROID_HOME = /Users/markusnissl/Library/Android/sdk
    • ANDROID_SDK_ROOT = /Users/markusnissl/Library/Android/sdk
    • Java binary at: /Users/markusnissl/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/203.7583922/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.5.1, Build version 12E507
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2020.3)
    • Android Studio at /Users/markusnissl/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/203.7583922/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)

[✓] IntelliJ IDEA Ultimate Edition (version 2021.2)
    • IntelliJ at /Users/markusnissl/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 58.0.3
    • Dart plugin version 211.7727

[✓] Connected device (4 available)
    • Pixel 3 (mobile) • 89TX0G7GP                 • android-arm64  • Android 11 (API 30)
    • iPhone (mobile)  • 00008030-000E659C3E87802E • ios            • iOS 14.7.1
    • macOS (desktop)  • macos                     • darwin-arm64   • macOS 11.5.2 20G95 darwin-arm
    • Chrome (web)     • chrome                    • web-javascript • Google Chrome 93.0.4577.63

• No issues found!
```

If you need additional information, please let me know.