생명주기 이용
Flutter 앱의 **생명주기(Lifecycle)**를 잘 이해하고 활용하면, 앱이 사용자와 상호작용하는 동안의 상태를 효율적으로 관리할 수 있습니다. 생명주기를 활용하면 리소스 관리, 데이터 저장, UI 업데이트 등을 더 효과적으로 제어할 수 있어 앱 성능이 향상됩니다. 아래는 Flutter에서 생명주기를 활용하는 방법과 주의할 점들입니다.
1. 위젯 생명주기 활용 (특히 StatefulWidget)
StatefulWidget은 위젯의 상태가 변할 때마다 재빌드됩니다. 이를 통해 위젯의 상태 변화를 감지하고 관리할 수 있으며, 각 생명주기 메서드를 사용하여 특정 이벤트나 기능을 트리거할 수 있습니다.
StatefulWidget 생명주기 메서드 활용
- initState(): 위젯이 처음 생성될 때 한 번 호출됩니다. 여기에서는 초기화가 필요한 데이터나 리소스를 설정하거나, API 요청을 시작할 수 있습니다.
@override
void initState() {
super.initState();
// 데이터 초기화나 API 호출 시작
}
didChangeDependencies(): initState() 이후 또는 부모 위젯의 변경 사항이 발생할 때 호출됩니다. InheritedWidget과 같은 상위 요소의 데이터를 받아 처리할 때 사용합니다.
@override
void didChangeDependencies() {
super.didChangeDependencies();
// 부모 위젯 데이터 변경 반영
}
build(): 위젯이 화면에 그려질 때마다 호출됩니다. build() 메서드는 위젯 트리를 반환하는데, 위젯의 변경된 상태를 반영합니다.
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Example')),
body: Center(child: Text('Hello')),
);
}
- didUpdateWidget(): StatefulWidget이 갱신되거나, 위젯이 재구성될 때 호출됩니다. 기존 상태를 유지하면서 새로운 데이터를 반영하는 데 사용합니다.
- dispose(): 위젯이 제거되거나 앱에서 사라질 때 호출됩니다. 여기서는 메모리 관리 측면에서 리소스를 해제하거나 Stream 또는 AnimationController와 같은 객체를 닫는 데 유용합니다
@override
void dispose() {
// 리소스 해제
super.dispose();
}
2. 앱 생명주기 활용 (App Lifecycle)
앱이 실행되면서 시스템과의 상호작용에 따라 발생하는 생명주기는 앱 전체의 상태를 제어할 수 있습니다. 예를 들어 앱이 백그라운드로 전환되거나, 다시 포그라운드로 돌아올 때 수행할 작업을 정의할 수 있습니다.
Flutter의 WidgetsBindingObserver를 활용하면 앱의 생명주기 변화를 감지할 수 있습니다.
앱 생명주기 메서드 활용
- didChangeAppLifecycleState: 앱이 포그라운드, 백그라운드, 중지 상태로 전환될 때 호출됩니다. 이를 통해 앱의 상태를 관리할 수 있습니다
class MyAppState extends State<MyApp> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this); // 옵저버 등록
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
// 앱이 백그라운드로 전환될 때 호출
} else if (state == AppLifecycleState.resumed) {
// 앱이 포그라운드로 복귀할 때 호출
}
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this); // 옵저버 해제
super.dispose();
}
}
3. 생명주기를 활용한 상태 및 리소스 관리
생명주기 메서드를 통해 특정 작업을 수행할 때, 이를 활용해 앱의 상태를 효율적으로 관리할 수 있습니다.
- 초기화 (initState): 앱이나 위젯이 처음 실행될 때 초기화 작업을 수행합니다. 여기서 데이터 로딩을 시작하거나 API 통신을 설정할 수 있습니다.
- 데이터 저장 및 회복 (didChangeAppLifecycleState): 앱이 백그라운드로 전환될 때 필요한 데이터를 저장하고, 다시 포그라운드로 돌아올 때 해당 데이터를 회복합니다.
- 리소스 해제 (dispose): 스트림, 이벤트 리스너 등 메모리를 사용하는 리소스를 해제하여 메모리 누수를 방지합니다.
4. 예시: 실시간 데이터 업데이트
예를 들어, 실시간 데이터를 스트리밍해야 하는 채팅 앱을 만들었다고 가정해보겠습니다.
- initState()에서 스트림 구독 시작: 위젯이 생성될 때 데이터 스트림을 구독하여 실시간 채팅 데이터를 수신합니다.
- didChangeAppLifecycleState에서 앱 상태에 따라 스트림 일시 정지 및 재개: 사용자가 앱을 닫거나 다른 화면으로 이동하면 스트림을 일시 정지하고, 다시 돌아올 때 재개합니다.
- dispose()에서 스트림 해제: 위젯이 사라질 때 스트림 구독을 취소하여 메모리를 해제합니다.
class ChatScreenState extends State<ChatScreen> with WidgetsBindingObserver {
StreamSubscription? _chatSubscription;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_chatSubscription = chatStream.listen((data) {
// 새로운 메시지 처리
});
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
_chatSubscription?.pause(); // 백그라운드에서 일시 정지
} else if (state == AppLifecycleState.resumed) {
_chatSubscription?.resume(); // 포그라운드에서 재개
}
}
@override
void dispose() {
_chatSubscription?.cancel(); // 리소스 해제
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
이와 같이 생명주기를 활용하면 앱의 상태와 리소스를 효율적으로 관리하고, 필요할 때만 업데이트하거나 리소스를 사용할 수 있습니다. 이는 사용자 경험을 개선하고, 앱 성능을 최적화하는 데 큰 도움이 됩니다.