Yazılar4 dk okuma
Effortless Lifecycle Management in Flutter Applications
In this article, we will delve into the details of an abstract class called AppLifecycleManager, designed to make lifecycle management in Flutter applications easier and more organized.

Hello Everyone!
App lifecycle management is a cornerstone in the app development process. As modern mobile applications offer increasingly complex features to meet user needs, they must behave appropriately when in the foreground, background, or closed states. Such scenarios require developers to not only deliver functionality but also to optimize resource management and user experience.
As your application grows, the operations tied to the app lifecycle can become more complex. For instance, running specific tasks in the background, maintaining sessions while the app is closed, or ensuring a seamless user experience when the app comes to the foreground are all requirements that demand careful structuring and management.
In this article, we will delve into the details of an abstract class called AppLifecycleManager, designed to make lifecycle management in Flutter applications easier and more organized. This structure allows you to manage lifecycle-related operations from a central point, making your development process more modular and sustainable.

What is AppLifecycleManager?
By using AppLifecycleListener, you can make your code more organized and readable, focusing only on specific events you are interested in, thus managing your code in a more sustainable way.
For this reason, AppLifecycleManager incorporates the AppLifecycleListener class to effectively manage operations tied to your app’s lifecycle. This structure allows you to organize and control actions triggered during different app states (e.g., resume, pause, hide, etc.)
AppLifecycleManager provides three core methods:
- Adding lifecycle functions (
add): You can add functions that will be triggered during lifecycle events, such as when your app goes to the background or comes to the foreground. - Removing functions (
remove): You can remove lifecycle functions that are no longer needed. - Clearing all functions (
clear): You can clear all lifecycle functions at once.
abstract interface class AppLifecycleManager {
factory AppLifecycleManager.instance() => _AppLifecycleManagerImpl();
Future<void> add(IAppLifecycleUseCase usecase);
void remove(IAppLifecycleUseCase usecase);
void clear();
}
AppLifecycleManager Concrete Class
final class _AppLifecycleManagerImpl implements AppLifecycleManager {
_AppLifecycleManagerImpl() {
_listenLifecycle();
}
final List<IAppLifecycleUseCase> _usecases = [];
@override
Future<void> add(IAppLifecycleUseCase usecase) async {
try {
if (!_usecases.any((element) => element.id == usecase.id)) {
_usecases.add(usecase);
await usecase.init();
}
} catch (e) {
AppLogger.e(e);
}
}
@override
void remove(IAppLifecycleUseCase usecase) {
try {
_usecases.removeWhere((element) => element.id == usecase.id);
usecase.dispose();
} catch (e) {
AppLogger.e(e);
}
}
void _listenLifecycle() {
AppLifecycleListener(
onDetach: () async {
for (final usecase in _usecases) {
await usecase.onDetach();
}
},
onResume: () async {
for (final usecase in _usecases) {
await usecase.onResume();
}
},
onPause: () async {
for (final usecase in _usecases) {
await usecase.onPause();
}
},
onHide: () async {
for (final usecase in _usecases) {
await usecase.onHide();
}
},
onInactive: () async {
for (final usecase in _usecases) {
await usecase.onInactive();
}
},
onShow: () async {
for (final usecase in _usecases) {
await usecase.onShow();
}
},
);
}
@override
void clear() {
_usecases.clear();
}
}
IAppLifecycleUseCase
Each use case implements the IAppLifecycleUseCase interface. This structure provides methods to handle lifecycle events:
abstract class IAppLifecycleUseCase {
AppLifecycleUseCase get id;
Future<void> init() {}
void dispose() {}
Future<void> onDetach() {}
Future<void> onResume() {}
Future<void> onPause() {}
Future<void> onHide() {}
Future<void> onInactive() {}
Future<void> onShow() {}
}
AppLifecycleUseCase
AppLifecycleUseCase is an AppLifecycleUseCase that defines different use cases responding to the application’s lifecycle events. This enum provides a unique identifier for each use case, enabling them to be easily managed and distinguished by AppLifecycleManager and IAppLifecycleUseCase.
enum AppLifecycleUseCase {
sessionTimeout;
}
Example: SessionTimeoutUseCase
Below is an example of a separate class that implements the IAppLifecycleUseCase interface. This class provides functionality to check if the user’s session has timed out and redirect the user to the login screen.
final class SessionTimeoutUseCase extends IAppLifecycleUseCase {
SessionTimeoutUseCase({
required AuthFacade authFacade,
required NavigationService navigationService,
}) : _authFacade = authFacade,
_navigationService = navigationService;
final AuthFacade _authFacade;
final NavigationService _navigationService;
@override
AppLifecycleUseCase id = AppLifecycleUseCase.sessionTimeout;
@override
Future<void> onInactive() async {
// Checks if the user's session is active.
final isSessionActive = await _authFacade.isSessionActive();
if (!isSessionActive) {
// Session has ended, redirect the user to the login screen.
await _navigateToLogin();
}
}
@override
Future<void> onResume() async {
// Can refresh the user's session duration.
await _authFacade.refreshSession();
}
Future<void> _navigateToLogin() async {
// Performs the redirection process.
await _navigationService.navigateToLogin();
}
}
Use Case:
final lifecycleManager = AppLifecycleManager.instance();
final sessionTimeoutUseCase = SessionTimeoutUseCase(
authFacade: AuthFacade(),
navigationService: NavigationService(),
);
lifecycleManager.add(sessionTimeoutUseCase);