각 Fragment
인스턴스에는 고유한 수명 주기가 있습니다. 사용자가 앱을 탐색하거나 앱과 상호작용할 때 프래그먼트는 화면에서 추가 또는 삭제되거나 화면에 들어가고 나오면서 수명 주기의 여러 상태 간에 전환하게 됩니다.
수명 주기를 관리하기 위해 Fragment
는 LifecycleOwner
를 구현하여, getLifecycle()
메서드를 통해 액세스할 수 있는 Lifecycle
객체를 노출합니다.
가능한 각 Lifecycle
상태는 Lifecycle.State
열거형으로 표시됩니다.
Lifecycle
위에 Fragment
를 빌드하면 수명 주기 인식 구성요소로 수명 주기 처리에 사용할 수 있는 기법과 클래스를 사용할 수 있습니다.
예를 들어 수명 주기 인식 구성요소를 사용하여 기기의 위치를 화면에 표시할 수 있습니다. 이 구성요소는 프래그먼트가 활성 상태가 되면 자동으로 수신 대기를 시작하고 프래그먼트가 비활성 상태로 전환되면 자동으로 수신 대기를 중지할 수 있습니다.
LifecycleObserver
를 사용하는 것의 대안으로, Fragment
클래스에는 프래그먼트 수명 주기의 각 변경에 대응하는 콜백 메서드가 포함되어 있습니다. onCreate()
, onStart()
, onResume()
, onPause()
, onStop()
, onDestroy()
가 포함되어 있습니다.
프래그먼트의 뷰에는 프래그먼트의 Lifecycle
의 뷰와 독립적으로 관리되는 별도의 Lifecycle
이 있습니다. 프래그먼트는 getViewLifecycleOwner()
또는 getViewLifecycleOwnerLiveData()
를 사용하여 액세스할 수 있는, 관련 뷰의 LifecycleOwner
를 관리합니다.
뷰의 Lifecycle
에 액세스할 수 있는 권한이 있으면 수명 주기 인식 구성요소가 프래그먼트의 뷰가 존재하는 동안에만 작업(예: 화면 표시 전용의 LiveData
관찰)해야 하는 상황에 유용합니다.
이 항목에서는 Fragment
수명 주기에 관해 자세히 논의하고, 프래그먼트의 수명 주기 상태를 확인하는 일부 규칙을 설명하며, Lifecycle
상태와 프래그먼트 수명 주기 콜백 간의 관계를 표시하는 방법을 보여줍니다.
프래그먼트 및 프래그먼트 관리자
프래그먼트는 인스턴스화되면 INITIALIZED
상태에서 시작됩니다. 프래그먼트가 프래그먼트의 나머지 수명 주기를 전환하도록 하려면 프래그먼트를 FragmentManager
에 추가해야 합니다. FragmentManager
가 프래그먼트가 어떤 상태여야 하는지 확인한 다음 그 상태로 전환하는 일을 담당합니다.
프래그먼트 수명 주기를 벗어나면 FragmentManager
는 프래그먼트를 호스트 활동에 연결하고 프래그먼트가 더 이상 사용되지 않을 때는 프래그먼트를 분리하는 작업도 합니다. Fragment
클래스에는 두 가지 콜백 메서드 onAttach()
와 onDetach()
가 있습니다. 이러한 메서드는 관련 이벤트 중 하나가 발생했을 때 작업을 위해 재정의할 수 있습니다.
onAttach()
콜백은 프래그먼트가 FragmentManager
에 추가되었을 때 호스트 활동에 연결되면 호출됩니다. 이 시점에 프래그먼트는 활성 상태이며 FragmentManager
가 수명 주기 상태를 관리하고 있습니다. 이 시점에서 findFragmentById()
같은 FragmentManager
메서드가 이 프래그먼트를 반환합니다.
onAttach()
는 항상 수명 주기 상태 변경 전에 호출됩니다.
onDetach()
콜백은 프래그먼트가 FragmentManager
에서 삭제되었을 때 호스트 활동에서 분리되면 호출됩니다. 프래그먼트가 더 이상 활성 상태가 아니므로 findFragmentById()
를 사용하여 더 이상 검색할 수 없습니다.
onDetach()
는 수명 주기 상태 변경 후에 항상 호출됩니다.
참고로, 이러한 콜백은 FragmentTransaction
메서드 attach()
및 detach()
와 연관이 없습니다.
이러한 메서드에 관한 자세한 내용은 프래그먼트 트랜잭션을 참조하세요.
프래그먼트 수명 주기 상태 및 콜백
프래그먼트의 수명 주기 상태를 결정할 때 FragmentManager
는 다음 사항을 고려합니다.
- 프래그먼트의 최대 상태는
FragmentManager
에 의해 결정됩니다. 프래그먼트는FragmentManager
의 상태를 벗어나 진행될 수 없습니다. FragmentTransaction
의 일부로setMaxLifecycle()
을 사용하여 프래그먼트에 최대 수명 주기 상태를 설정할 수 있습니다 .- 프래그먼트의 수명 주기 상태는 상위 요소보다 클 수 없습니다. 예를 들어 상위 프래그먼트 또는 상위 활동은 하위 프래그먼트보다 먼저 시작해야 합니다. 마찬가지로 하위 프래그먼트는 상위 프래그먼트 또는 상위 활동보다 먼저 중지되어야 합니다.
그림 1은 프래그먼트의 각 Lifecycle
상태와 그 상태가 프래그먼트의 수명 주기 콜백은 물론 프래그먼트의 뷰 Lifecycle
과 어떤 관련이 있는지를 보여줍니다.
프래그먼트는 수명 주기를 거치며 상태를 따라 위아래로 이동합니다. 예를 들어 백 스택 상단에 추가된 프래그먼트는CREATED
에서 STARTED
를 거쳐 RESUMED
까지 위로 이동합니다. 반대로 프래그먼트가 백 스택에서 사라진 경우 RESUMED
에서 STARTED
를 거쳐 CREATED
로, 최종적으로 DESTROYED
상태가 될 때까지 아래로 이동합니다.
상향 상태 전환
프래그먼트는 수명 주기 상태를 통해 위로 이동할 때 먼저 새 상태와 관련된 수명 주기 콜백을 호출합니다. 이 콜백이 끝나면 관련 Lifecycle.Event
가 프래그먼트의 Lifecycle
에 의해 관찰자로 보내집니다. 인스턴스화된 경우 그다음에는 프래그먼트의 뷰 Lifecycle
에 의해 보내집니다.
프래그먼트 CREATED
프래그먼트가 CREATED
상태에 도달하면, 이미 프래그먼트는 FragmentManager
에 추가되고 onAttach()
메서드가 호출된 상태입니다.
이 위치는 프래그먼트의 SavedStateRegistry
를 통해 프래그먼트 자체와 연결된 저장 상태를 복원하는 데 적절합니다.
참고로, 이 시점에는 프래그먼트의 뷰가 생성되지 않았으며 프래그먼트의 뷰와 관련된 모든 상태는 뷰가 생성된 이후에만 복원해야 합니다.
이 전환은 onCreate()
콜백을 호출합니다. 이 콜백은 이전에 onSaveInstanceState()
에 의해 저장된 상태를 포함하는 savedInstanceState
Bundle
인수도 수신합니다.
프래그먼트가 처음 생성될 때는 savedInstanceState
가 null
값을 갖지만 개발자가 onSaveInstanceState()
을 재정의하지 않더라도 이후 생성에서는 항상 null이 아닙니다. 자세한 내용은 프래그먼트와 함께 상태 저장을 참조하세요.
프래그먼트 CREATED 및 뷰 INITIALIZED
Fragment
가 유효한 View
인스턴스를 제공하는 경우에만 프래그먼트의 뷰 Lifecycle
이 생성됩니다. 대부분의 경우 @LayoutId
(적절한 시간에 뷰를 자동으로 확장함)를 사용하는 프래그먼트 생성자를 사용할 수 있습니다. 또한 onCreateView()
를 재정의하여 프로그래매틱 방식으로 프래그먼트의 뷰를 확장하거나 만들 수 있습니다.
프래그먼트의 뷰가 null이 아닌 View
로 인스턴스화된 경우(또는 이 경우에만) 그 View
는 프래그먼트에 설정되고, getView()
를 사용하여 검색할 수 있습니다. 그런 다음 getViewLifecycleOwnerLiveData()
가 프래그먼트의 뷰에 대응하는 새로운 INITIALIZED
LifecycleOwner
로 업데이트됩니다. 이 시점에서는 onViewCreated()
수명 주기 콜백도 호출됩니다.
이 위치는 뷰의 초기 상태를 설정하고, 프래그먼트의 뷰를 업데이트하는 콜백을 갖는 LiveData
인스턴스를 관찰하며, 프래그먼트의 뷰에서 RecyclerView
또는 ViewPager2
인스턴스에 어댑터를 설정하기에 적합합니다.
프래그먼트 및 뷰 CREATED
프래그먼트의 뷰가 생성되면 이전 뷰 상태(있는 경우)가 복원되고 뷰의 Lifecycle
이 CREATED
상태로 전환됩니다. 또한 뷰 수명 주기 소유자는 ON_CREATE
이벤트를 관찰자로 보냅니다. 여기에서 프래그먼트의 뷰와 관련된 모든 추가 상태를 복원해야 합니다.
이 전환에서는 onViewStateRestored()
콜백도 호출합니다.
프래그먼트 및 뷰 STARTED
수명 주기 인식 구성요소를 프래그먼트의 STARTED
상태와 연결하는 것이 좋습니다. 이 상태와 연결하면 프래그먼트의 뷰(생성된 경우)를 사용할 수 있고 프래그먼트의 하위 FragmentManager
에서 FragmentTransaction
을 안전하게 실행할 수 있기 때문입니다. 프래그먼트의 뷰가 null이 아니면 프래그먼트의 Lifecycle
이 STARTED
로 전환된 직후 프래그먼트의 뷰 Lifecycle
이 STARTED
로 전환됩니다.
프래그먼트가 STARTED
가 되면 onStart()
콜백이 호출됩니다.
프래그먼트 및 뷰 RESUMED
프래그먼트가 표시되면 모든 Animator
효과와 Transition
효과가 완료되어 프래그먼트를 사용자 상호작용에 사용할 수 있습니다. 프래그먼트의 Lifecycle
이 RESUMED
상태로 전환되고 onResume()
콜백이 호출됩니다.
RESUMED
로 전환된 것은 사용자가 이제 프래그먼트와 상호작용할 수 있음을 나타내는 적절한 신호입니다. RESUMED
가 아닌 프래그먼트는 뷰에 포커스를 수동으로 설정하거나 입력 메서드 공개 상태를 처리하려고 시도해서는 안 됩니다.
하향 상태 전환
프래그먼트가 하위 수명 주기 상태 방향으로 아래로 이동하면 관련 Lifecycle.Event
가 프래그먼트의 뷰 Lifecycle
에 의해 관찰자로 보내집니다. 인스턴스화된 경우 그다음에는 프래그먼트의 Lifecycle
에 의해 보내집니다. 프래그먼트의 수명 주기 이벤트가 보내지면 프래그먼트가 관련 수명 주기 콜백을 호출합니다.
프래그먼트 및 뷰 STARTED
사용자가 프래그먼트를 벗어나기 시작할 때에도 프래그먼트가 표시된 상태이면 프래그먼트와 관련 뷰의 Lifecycle
은 다시 STARTED
상태로 전환되고 관찰자에 ON_PAUSE
이벤트를 보냅니다. 그런 다음 프래그먼트는 onPause()
콜백을 호출합니다.
프래그먼트 및 뷰 CREATED
프래그먼트가 더 이상 표시되지 않으면 프래그먼트와 관련 뷰의 Lifecycle
은 CREATED
상태로 전환되고 관찰자에 ON_STOP
이벤트를 보냅니다. 이 상태 전환은 중지 중인 상위 활동 또는 상위 프래그먼트에 의해 트리거될 뿐 아니라, 상위 활동 또는 상위 프래그먼트의 상태 저장에 의해서도 트리거됩니다. 이 동작으로 프래그먼트의 상태가 저장되기 전에 ON_STOP
이벤트가 호출됩니다. 그렇게 되면 ON_STOP
이벤트가 하위 FragmentManager
에서 FragmentTransaction
을 안전하게 실행할 수 있는 마지막 지점이 됩니다.
그림 2에 나와 있는 것처럼 onStop()
콜백의 순서와 onSaveInstanceState()
를 사용한 상태 저장은 API 수준에 따라 다릅니다. API 28 이전의 모든 API 수준에서는 onSaveInstanceState()
가 onStop()
이전에 호출됩니다.
API 수준 28 이상에서는 호출 순서가 반대가 됩니다.
프래그먼트 CREATED 및 뷰 DESTROYED
나가기 애니메이션과 전환이 모두 완료되고 프래그먼트의 뷰가 창에서 분리되면 프래그먼트의 뷰 Lifecycle
이 DESTROYED
상태로 전환되고 ON_DESTROY
이벤트를 관찰자에 보냅니다. 그런 다음 프래그먼트가 onDestroyView()
콜백을 호출합니다. 이 시점에서 프래그먼트의 뷰는 수명 주기의 끝에 도달했으며 getViewLifecycleOwnerLiveData()
가 null
값을 반환합니다.
이때 프래그먼트 뷰의 모든 참조를 삭제해야 합니다. 그래야 프래그먼트의 뷰에서 가비지를 수집할 수 있습니다.
프래그먼트 DESTROYED
프래그먼트가 삭제되거나 FragmentManager
가 소멸되면 프래그먼트의 Lifecycle
이 DESTROYED
상태로 전환되고 ON_DESTROY
이벤트를 관찰자에 전송합니다. 그런 다음 프래그먼트가 onDestroy()
콜백을 호출합니다. 이 시점에서 프래그먼트는 수명 주기의 끝에 도달한 상태입니다.
추가 리소스
프래그먼트 수명 주기와 관련된 자세한 내용은 다음 추가 리소스를 참조하세요.