import 'dart:async'; import 'package:flutter/widgets.dart'; import '/locator.dart'; import 'logging_service.dart'; typedef AddLifeCycleListener = void Function({ required void Function(AppLifecycleState appLifecycleState) listener, required String tag, bool tryCallListenerOnAdd, }); typedef RemoveLifeCycleListener = Future Function({required String tag}); /// Used to observe the current app lifecycle state. class AppLifecycleService with WidgetsBindingObserver { AppLifecycleService({ required LoggingService loggingService, }) : _loggingService = loggingService { WidgetsBinding.instance.addObserver(this); _appLifeCycleState = WidgetsBinding.instance.lifecycleState; } final LoggingService _loggingService; late final StreamController _lifecycleStateStreamController = StreamController.broadcast(); final Map> _appLifecycleSubscriptions = {}; AppLifecycleState? _appLifeCycleState; AppLifecycleState? get appLifeCycleState => _appLifeCycleState; Future dispose() async { _loggingService.info('Disposing app lifecycle service..'); WidgetsBinding.instance.removeObserver(this); for (final subscription in _appLifecycleSubscriptions.values) { await subscription.cancel(); } _appLifecycleSubscriptions.clear(); _loggingService.good('App lifecycle service disposed!'); } @override void didChangeAppLifecycleState(AppLifecycleState state) { try { _appLifeCycleState = state; _lifecycleStateStreamController.add(state); } catch (error, stackTrace) { _loggingService.error( 'Something went wrong with ${state.name} inside the didChangeAppLifeCycleState method', error, stackTrace, ); } super.didChangeAppLifecycleState(state); } void addListener({ required void Function(AppLifecycleState appLifecycleState) listener, required String tag, bool tryCallListenerOnAdd = true, }) { try { if (_appLifecycleSubscriptions.containsKey(tag)) { _loggingService.warning('Tag already active, returning'); } else { final message = 'Adding $tag appLifecycleState listener'; _loggingService.info('$message..'); if (_appLifeCycleState != null && tryCallListenerOnAdd) listener(_appLifeCycleState!); _appLifecycleSubscriptions[tag] = _lifecycleStateStreamController.stream.listen(listener); _loggingService.good('$message success!'); } } catch (error, stackTrace) { _loggingService.error( 'Something went wrong adding $tag appLifecycleState listener', error, stackTrace, ); } } Future removeListener({required String tag}) async { try { final message = 'Removing $tag appLifecycleState listener'; _loggingService.info('$message..'); final subscription = _appLifecycleSubscriptions[tag]; if (subscription != null) { await subscription.cancel(); _appLifecycleSubscriptions.remove(tag); _loggingService.good('$message success!'); } else { _loggingService.warning('Subscription was not found'); } } catch (error, stackTrace) { _loggingService.error( 'Something went wrong removing $tag appLifecycleState listener', error, stackTrace, ); } } static AppLifecycleService get locate => Locator.locate(); }