fix: make async initialization and dispose calls in separate async function
Showing
2 changed files
with
38 additions
and
17 deletions
| @@ -339,6 +339,7 @@ class MethodChannelMobileScanner extends MobileScannerPlatform { | @@ -339,6 +339,7 @@ class MethodChannelMobileScanner extends MobileScannerPlatform { | ||
| 339 | 339 | ||
| 340 | @override | 340 | @override |
| 341 | Future<void> dispose() async { | 341 | Future<void> dispose() async { |
| 342 | + await updateScanWindow(null); | ||
| 342 | await stop(); | 343 | await stop(); |
| 343 | } | 344 | } |
| 344 | } | 345 | } |
| @@ -135,7 +135,7 @@ class MobileScanner extends StatefulWidget { | @@ -135,7 +135,7 @@ class MobileScanner extends StatefulWidget { | ||
| 135 | 135 | ||
| 136 | class _MobileScannerState extends State<MobileScanner> | 136 | class _MobileScannerState extends State<MobileScanner> |
| 137 | with WidgetsBindingObserver { | 137 | with WidgetsBindingObserver { |
| 138 | - late final controller = widget.controller ?? MobileScannerController(); | 138 | + late final MobileScannerController controller; |
| 139 | 139 | ||
| 140 | /// The current scan window. | 140 | /// The current scan window. |
| 141 | Rect? scanWindow; | 141 | Rect? scanWindow; |
| @@ -200,7 +200,6 @@ class _MobileScannerState extends State<MobileScanner> | @@ -200,7 +200,6 @@ class _MobileScannerState extends State<MobileScanner> | ||
| 200 | return ValueListenableBuilder<MobileScannerState>( | 200 | return ValueListenableBuilder<MobileScannerState>( |
| 201 | valueListenable: controller, | 201 | valueListenable: controller, |
| 202 | builder: (BuildContext context, MobileScannerState value, Widget? child) { | 202 | builder: (BuildContext context, MobileScannerState value, Widget? child) { |
| 203 | - | ||
| 204 | // If the controller is still initializing, show a black screen, or user provided placeholder | 203 | // If the controller is still initializing, show a black screen, or user provided placeholder |
| 205 | if (!value.isInitialized) { | 204 | if (!value.isInitialized) { |
| 206 | const Widget defaultPlaceholder = ColoredBox(color: Colors.black); | 205 | const Widget defaultPlaceholder = ColoredBox(color: Colors.black); |
| @@ -259,8 +258,21 @@ class _MobileScannerState extends State<MobileScanner> | @@ -259,8 +258,21 @@ class _MobileScannerState extends State<MobileScanner> | ||
| 259 | 258 | ||
| 260 | StreamSubscription? _subscription; | 259 | StreamSubscription? _subscription; |
| 261 | 260 | ||
| 262 | - @override | ||
| 263 | - void initState() { | 261 | + Future<void> initController() async { |
| 262 | + // TODO: This will be fixed in another PR | ||
| 263 | + // If debug mode is enabled, stop the controller first before starting it. | ||
| 264 | + // If a hot-restart is initiated, the controller won't be stopped, and because | ||
| 265 | + // there is no way of knowing if a hot-restart has happened, we must assume | ||
| 266 | + // every start is a hot-restart. | ||
| 267 | + // if (kDebugMode) { | ||
| 268 | + // try { | ||
| 269 | + // await controller.stop(); | ||
| 270 | + // } catch (e) { | ||
| 271 | + // // Don't do anything if the controller is already stopped. | ||
| 272 | + // debugPrint('$e'); | ||
| 273 | + // } | ||
| 274 | + // } | ||
| 275 | + | ||
| 264 | if (widget.onDetect != null) { | 276 | if (widget.onDetect != null) { |
| 265 | WidgetsBinding.instance.addObserver(this); | 277 | WidgetsBinding.instance.addObserver(this); |
| 266 | _subscription = controller.barcodes.listen( | 278 | _subscription = controller.barcodes.listen( |
| @@ -270,31 +282,39 @@ class _MobileScannerState extends State<MobileScanner> | @@ -270,31 +282,39 @@ class _MobileScannerState extends State<MobileScanner> | ||
| 270 | ); | 282 | ); |
| 271 | } | 283 | } |
| 272 | if (controller.autoStart) { | 284 | if (controller.autoStart) { |
| 273 | - controller.start(); | 285 | + await controller.start(); |
| 286 | + } | ||
| 287 | + } | ||
| 288 | + | ||
| 289 | + Future<void> disposeCamera() async { | ||
| 290 | + if (controller.autoStart) { | ||
| 291 | + await controller.stop(); | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + // Dispose default controller if not provided by user | ||
| 295 | + if (widget.controller == null) { | ||
| 296 | + await controller.dispose(); | ||
| 297 | + WidgetsBinding.instance.removeObserver(this); | ||
| 274 | } | 298 | } |
| 299 | + } | ||
| 300 | + | ||
| 301 | + @override | ||
| 302 | + void initState() { | ||
| 275 | super.initState(); | 303 | super.initState(); |
| 304 | + controller = widget.controller ?? MobileScannerController(); | ||
| 305 | + initController(); | ||
| 276 | } | 306 | } |
| 277 | 307 | ||
| 278 | @override | 308 | @override |
| 279 | void dispose() { | 309 | void dispose() { |
| 280 | - super.dispose(); | ||
| 281 | - | ||
| 282 | if (_subscription != null) { | 310 | if (_subscription != null) { |
| 283 | _subscription!.cancel(); | 311 | _subscription!.cancel(); |
| 284 | _subscription = null; | 312 | _subscription = null; |
| 285 | } | 313 | } |
| 286 | 314 | ||
| 287 | - if (controller.autoStart) { | ||
| 288 | - controller.stop(); | ||
| 289 | - } | ||
| 290 | - // When this widget is unmounted, reset the scan window. | ||
| 291 | - unawaited(controller.updateScanWindow(null)); | 315 | + disposeCamera(); |
| 292 | 316 | ||
| 293 | - // Dispose default controller if not provided by user | ||
| 294 | - if (widget.controller == null) { | ||
| 295 | - controller.dispose(); | ||
| 296 | - WidgetsBinding.instance.removeObserver(this); | ||
| 297 | - } | 317 | + super.dispose(); |
| 298 | } | 318 | } |
| 299 | 319 | ||
| 300 | @override | 320 | @override |
-
Please register or login to post a comment