Skip to content

Commit 300556d

Browse files
committed
⚡️ Improve camera initialize by adding lock
1 parent ddd442f commit 300556d

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

lib/src/internals/extensions.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import 'package:flutter/widgets.dart';
99
extension SafeSetStateExtension on State {
1010
FutureOr<void> safeSetState(FutureOr<dynamic> Function() fn) async {
1111
await fn();
12-
if (mounted) {
12+
if (mounted &&
13+
!context.debugDoingBuild &&
14+
context.owner?.debugBuilding != true) {
1315
// ignore: invalid_use_of_protected_member
1416
setState(() {});
1517
}

lib/src/widgets/camera_picker.dart

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ class CameraPickerState extends State<CameraPicker>
307307
/// 当前相机实例的控制器
308308
CameraController get controller => _controller!;
309309
CameraController? _controller;
310+
bool _shouldLockInitialize = false;
310311

311312
/// Available cameras.
312313
/// 可用的相机实例
@@ -477,7 +478,7 @@ class CameraPickerState extends State<CameraPicker>
477478
}
478479
if (state == AppLifecycleState.inactive) {
479480
c.dispose();
480-
} else if (state == AppLifecycleState.resumed && !c.value.isInitialized) {
481+
} else if (state == AppLifecycleState.resumed && !_shouldLockInitialize) {
481482
// Drop initialize when the controller has been already initialized.
482483
// This will typically resolve the lifecycle issue on iOS when permissions
483484
// are requested for the first time.
@@ -513,6 +514,7 @@ class CameraPickerState extends State<CameraPicker>
513514
final CameraController? _c = _controller;
514515
// Then unbind the controller from widgets, which requires a build frame.
515516
safeSetState(() {
517+
_shouldLockInitialize = true;
516518
_maxAvailableZoom = 1;
517519
_minAvailableZoom = 1;
518520
_currentZoom = 1;
@@ -541,6 +543,7 @@ class CameraPickerState extends State<CameraPicker>
541543
// After cameras fetched, judge again with the list is empty or not to
542544
// ensure there is at least an available camera for use.
543545
if (cameraDescription == null && (cameras.isEmpty)) {
546+
_shouldLockInitialize = false;
544547
handleErrorWithHandler(
545548
CameraException(
546549
'No CameraDescription found.',
@@ -601,7 +604,9 @@ class CameraPickerState extends State<CameraPicker>
601604
} catch (e) {
602605
handleErrorWithHandler(e, widget.onError);
603606
} finally {
604-
safeSetState(() {});
607+
safeSetState(() {
608+
_shouldLockInitialize = false;
609+
});
605610
}
606611
});
607612
}
@@ -791,7 +796,10 @@ class CameraPickerState extends State<CameraPicker>
791796
final XFile _file = await controller.takePicture();
792797
// Delay disposing the controller to hold the preview.
793798
Future<void>.delayed(const Duration(milliseconds: 500), () {
794-
controller.dispose();
799+
_controller?.dispose();
800+
safeSetState(() {
801+
_controller = null;
802+
});
795803
});
796804
final AssetEntity? entity = await CameraPickerViewer.pushToViewer(
797805
context,

0 commit comments

Comments
 (0)