본문 바로가기
new

Flutter App Lifecycle 이해하기: AppLifecycleState enum

by ftbd 2024. 3. 7.

Flutter 앱 개발 시 앱의 상태 변화를 관리하는 것은 매우 중요합니다. AppLifecycleState enum은 앱의 다양한 상태를 나타내는 열거형 상수이며, 이를 통해 앱의 상태 변화에 따라 적절한 행동을 취할 수 있습니다.

 

1. AppLifecycleState 정의

enum AppLifecycleState {
  /// The application is still hosted by a Flutter engine but is detached from
  /// any host views.
  ///
  /// ...
  detached,

  /// On all platforms, this state indicates that the application is in the
  /// default running mode...
  ///
  /// ...
  resumed,

  /// At least one view of the application is visible, but none have input
  /// focus...
  ///
  /// ...
  inactive,

  /// All views of an application are hidden...
  ///
  /// ...
  hidden,

  /// The application is not currently visible to the user, and not responding
  /// to user input...
  ///
  /// ...
  paused,
}

 

2. AppLifecycleState의 상태 종류

AppLifecycleState enum은 총 5가지의 상태를 포함합니다.

 

- detached (분리됨)

  • 앱은 아직 플러터 엔진에 연결되어 있지만, 모든 호스트 뷰(host view)와 분리된 상태입니다.
  • 앱은 초기화되기 전이나 모든 뷰가 분리된 후 (안드로이드 및 iOS에서만 해당) 이 상태에 놓입니다.
  • 이 상태에서는 엔진만 실행되고 뷰는 없습니다.
  • 이 상태는 모든 플랫폼에서 앱 실행 전 기본 상태이지만, iOS와 안드로이드에서만 실제로 발생합니다.

- resumed (재개됨)

  • 모든 플랫폼에서 실행 중이고 입력 초점이 있으며 화면에 표시되는 앱의 기본 실행 모드를 나타냅니다.
  • 안드로이드에서 이 상태는 플러터 호스트 뷰가 포커스를 가진 상태(Activity.onWindowFocusChanged가 true로 호출됨)이며 안드로이드의 "resumed" 상태와 일치합니다. 앱이 포커스를 잃었지만 (Activity.onWindowFocusChanged가 false로 호출됨) Activity.onPause가 아직 호출되지 않은 경우에도 앱은 inactive 상태일 수 있습니다.
  • iOS 및 macOS에서 이 상태는 앱이 전면 실행 활성 상태에서 실행되는 것과 일치합니다.

- inactive (비활성)

  • 앱의 적어도 하나의 뷰는 표시되지만, 어떤 뷰도 입력 초점을 가지고 있지 않습니다. 앱은 다른 측면에서는 정상적으로 실행됩니다.
  • 웹이 아닌 데스크톱 플랫폼에서 이 상태는 전면에 있지 않지만 여전히 보이는 창이 있는 응용 프로그램에 해당합니다.
  • 웹에서 이 상태는 입력 초점이 없는 창이나 탭에서 실행되는 응용 프로그램에 해당합니다.
  • iOS 및 macOS에서 이 상태는 플러터 호스트 뷰가 전면 비활성 상태에서 실행되는 것과 일치합니다. 앱은 전화 통화 중, TouchID 요청에 응답할 때, 앱 전환기 또는 제어 센터를 열 때, 또는 Flutter 앱을 호스팅하는 UIViewController가 전환 중일 때 이 상태로 전환됩니다.
  • 안드로이드에서 이 상태는 플러터 호스트 뷰가 안드로이드의 일시 중지 상태(Activity.onPause가 호출됨)에서 실행되거나, 안드로이드의 "resumed" 상태(Activity.onResume이 호출됨)지만 창 포커스가 없는 경우에 해당합니다. 앱은 부분적으로 가려지거나 다른 액티비티가 포커스를 가질 때, 분할 화면에서 실행 중인 현재 앱이 아닌 앱, 전화 통화로 인해 중단된 앱, 픽처 인 픽처 앱, 시스템 대화 상자, 다른 뷰 등에 의해 비활성화될 수 있습니다. 또한 알림 창 가림막이 내려져 있거나 응용 프로그램 전환기가 표시된 경우에도 비활성 상태가 됩니다.
  • 안드로이드와 iOS에서 이 상태의 앱은 언제든지 hidden 또는 paused 상태가 될 수 있다고 가정해야 합니다.

- hidden (숨김)

  • 앱이 일시 중지되기 직전 (iOS 및 안드로이드)이거나 최소화되었거나 더 이상 표시되지 않는 데스크톱(웹이 아닌 데스크톱)에 배치되었거나 더 이상 표시되지 않는 창 또는 탭에서 실행 중이기 때문에 응용 프로그램의 모든 뷰가 숨겨진 상태입니다.
  • iOS 및 안드로이드에서 모든 플랫폼에서 상태 머신을 동일하게 유지하기 위해 inactive 상태에서 paused 상태로 전환되기 전과 paused 상태에서 inactive 상태로 전환되기 전에 이 상태로의 전환이 합성됩니다. 이를 통해 개념적으로 앱이 "숨겨져" 있을 때를 알고 싶은 교차 플랫폼 구현은 단 하나의 처리기만 작성하면 됩니다.

- paused (일시 중지됨)

  • 앱이 현재 사용자에게 표시되지 않고 사용자 입력에 응답하지 않습니다.
  • 앱이 이 상태에 있으면 엔진은 PlatformDispatcher.onBeginFrame 및 PlatformDispatcher.onDrawFrame 콜백을 호출하지 않습니다.

 

3. AppLifecycleState 사용 이유

개발자는 WidgetsBindingObserver 클래스의 didChangeAppLifecycleState 메서드를 사용하여 앱의 상태 변화를 감지할 수 있습니다. 이를 통해 다음과 같은 작업을 수행할 수 있습니다.

  • 앱이 백그라운드로 전환될 때 네트워크 연결 종료, 위치 추적 중지 등 불필요한 작업 중단
  • 앱이 포그라운드로 복귀할 때 데이터 로딩, UI 업데이트 등 필요한 작업 수행
  • 앱이 완전히 종료될 때 리소스 해제, 데이터 저장 등 마무리 작업 수행