Flutter에서 Timer
클래스는 Dart의 dart:async
라이브러리에 정의되어 있으며, 시간 기반의 작업을 스케줄링하는 데 사용됩니다. Timer
를 사용하여 단일 시간 지연 후에 작업을 실행하거나, 주기적인 간격으로 반복 작업을 수행할 수 있습니다. 타이머 예제 두 가지를 통해서 사용하는 방법을 알아보겠습니다!
Timer
의 주요 기능
일회성 타이머 (Timer
): 지정된 시간이 경과한 후에 단 한 번 작업을 수행합니다.
Timer(Duration(seconds: 5), () {
// 5초 후에 실행될 코드
});
주기적 타이머 (Timer.periodic
): 지정된 간격으로 반복적으로 작업을 수행합니다.
Timer.periodic(Duration(seconds: 5), (Timer t) {
// 매 5초마다 반복적으로 실행될 코드
});
Timer
사용시 고려사항
- 생명주기 관리:
Timer
는 앱의 생명주기와 독립적으로 작동합니다. 따라서 위젯이 소멸되거나 더 이상 필요하지 않을 때Timer
를 적절히 취소해야 합니다. 이를 위해Timer
객체를 저장하고, 위젯이 소멸될 때 (dispose
메서드 내에서)Timer
를 취소하는 것이 좋습니다. - 백그라운드 상태: Flutter 앱이 백그라운드로 이동하면, 타이머의 동작은 플랫폼(iOS/Android)에 따라 다를 수 있습니다. 특히 iOS에서는 백그라운드 상태에서 타이머가 일시중지되거나 작동하지 않을 수 있습니다.
- 성능과 자원: 주기적인 타이머는 추가적인 시스템 자원을 사용하므로, 자원 사용을 최적화하기 위해 필요할 때만 타이머를 사용하는 것이 중요합니다.
타이머 예제 1
import 'dart:async';
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
Timer? _timer;
@override
void initState() {
super.initState();
_timer = Timer.periodic(Duration(seconds: 5), (Timer t) {
// 주기적으로 실행될 작업
});
}
@override
void dispose() {
_timer?.cancel(); // 타이머 취소
super.dispose();
}
@override
Widget build(BuildContext context) {
// UI 구성
}
}
이 예제에서 _timer
는 5초마다 반복적으로 작업을 수행하는 주기적 타이머입니다. dispose
메서드에서 타이머를 취소하여 위젯이 소멸될 때 자원을 해제합니다. 이러한 방식으로 Timer
를 사용하면 효과적으로 시간 기반 작업을 스케줄링할 수 있습니다.
타이머 예제2
Flutter 앱에서 백그라운드로 이동할 때 타이머를 멈추고 싶다면, WidgetsBindingObserver
를 사용하여 앱의 생명주기 상태를 감지하고 그에 따라 타이머를 시작하거나 중지할 수 있습니다. WidgetsBindingObserver
는 앱이 포그라운드로 이동하거나 백그라운드로 이동하는 것을 감지할 수 있으며, 이를 통해 타이머의 동작을 제어할 수 있습니다.
다음은 WidgetsBindingObserver
를 사용하여 백그라운드로 이동할 때 타이머를 멈추고, 다시 포그라운드로 돌아왔을 때 타이머를 재시작하는 방법을 보여주는 코드 예시입니다:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class PremiumController extends GetxController with WidgetsBindingObserver {
Timer? _periodicTimer;
@override
void onInit() {
super.onInit();
WidgetsBinding.instance.addObserver(this); // 옵저버 추가
_startTimer(); // 타이머 시작
}
@override
void onClose() {
_stopTimer(); // 타이머 정리
WidgetsBinding.instance.removeObserver(this); // 옵저버 제거
super.onClose();
}
void _startTimer() {
_periodicTimer = Timer.periodic(Duration(minutes: 1), (Timer t) {
updateAccessStatus();
});
}
void _stopTimer() {
_periodicTimer?.cancel();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// 앱이 포그라운드로 돌아왔을 때
_startTimer();
} else if (state == AppLifecycleState.paused) {
// 앱이 백그라운드로 이동했을 때
_stopTimer();
}
}
void updateAccessStatus() {
// ... 상태 업데이트 로직 ...
}
}
위 코드에서는 WidgetsBindingObserver
를 구현하여 앱의 생명주기 상태 변화를 감지합니다. didChangeAppLifecycleState
메서드는 앱의 상태가 변경될 때 호출되며, 이를 통해 타이머를 제어할 수 있습니다. 앱이 백그라운드로 이동(paused
)할 때 타이머를 중지하고, 다시 포그라운드(resumed
)로 돌아올 때 타이머를 재시작합니다.
이렇게 하면 앱이 백그라운드에서는 타이머를 멈추고, 포그라운드로 돌아올 때 필요한 작업을 계속할 수 있게 됩니다.