플러터의 생애 주기는 기본적으로 앱이 실행되면서부터 종료되기까지의 상태 변화 과정을 나타낸다. 여기서 더 세분화하자면 App/Widget의 두 가지 차원에서 이해가 가능하다. 1탄에서는 App 차원에서의 생명주기에 대해 설명해 보고자 한다.
앱을 비활성 상태(예: 백그라운드로 전환)/활성 상태로 변경 시 감지할 수 있다. 본래 Android, IOS OS의 각 생명주기의 형태가 다르지만 flutter는 이를 추상화하여 총 5단계로서 제공한다.
출처 : https://api.flutter.dev/flutter/widgets/AppLifecycleListener-class.html
- resumed : 앱이 활성화되어 유저가 조작할 수 있음. 단, 최초의 앱 실행 때는 이 이벤트가 발생하지 않음.
- inactive : 앱이 화면에 보이긴 해도 유저가 조작할 수 없음.
- hidden : 앱의 뷰가 숨겨진 상태. inactive와 paused 상태로 전환 시 거치는 중간 상태.
- paused : 앱이 백그라운드로 이동. 유저와 상호작용 불가능.
- detached : 위젯이 flutter 엔진에서 분리됨. 주로 앱 강제 종료, 플러터 엔진 소멸 시 나타남.
* 각 단계들은 화살표의 방향대로 상태가 변화하고, 중간을 가로질러 바뀌지 않는다. (예 : paused - resumed으로 상태변화 불가. paused - hidden - inactive - resumed 순으로 변화.)
테스트 환경
- Android 테스트 폰 - 갤럭시 A80, 갤럭시 폴드 3
- IOS 테스트 폰 - 아이폰13
* 모두 실 기기로 테스트했으며 가상 기기와 결과가 다를 수 있음을 알려드립니다.
Stateful 위젯 생성 - WidgetsBindingObserver 객체를 상속받은 뒤(with WidgetsBindingObserver) 위와 같은 코드를 추가하여 테스트
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
switch (state) {
case AppLifecycleState.inactive:
print('inactive');
break;
case AppLifecycleState.detached:
print('detached');
break;
case AppLifecycleState.resumed:
print('resumed');
break;
case AppLifecycleState.paused:
print('paused');
break;
case AppLifecycleState.hidden:
print('hidden');
break;
}
}
- minimize 했을 시
Android : inactive - hidden - paused
IOS : inactive
- minimize된 앱을 다시 foreground로 되돌렸을 시
Android : hidden - inactive - resumed
IOS : resumed
- Background 했을 시
Android : inactive - hidden - paused
IOS : inactive - hidden - paused
- Background로 옮겨진 앱을 다시 foreground로 되돌렸을 시
Android : hidden - inactive - resumed
IOS : hidden - inactive - resumed
- minimize된 App을 Kill 했을 시
Android : (inactive - hidden - paused까지 되어있는 상태) - detached가 뜨지않음.
IOS : (inactive까지 되어있는 상태) - hidden - paused - detached