라떼는말이야

[Android] 실습으로 알아보는 프래그먼트 생명주기 : Android fragment lifecycle 본문

안드로이드

[Android] 실습으로 알아보는 프래그먼트 생명주기 : Android fragment lifecycle

MangBaam 2021. 12. 10. 02:34
반응형

시작하기 전에...

로그를 남기는 방법이나 액티비티의 생명 주기에 관해서 아래의 링크에서 상세히 다뤘었다. 아직 액티비티의 생명 주기에 익숙하지 않다면 먼저 공부를 하고 오는 것을 추천한다.

프래그먼트의 생명 주기는 액티비티의 생명 주기와 비슷한 면이 많이 때문이다.

2021.12.09 - [Android] 실습으로 알아보는 액티비티 생명주기 : Android activity lifecycle

 

[Android] 실습으로 알아보는 액티비티 생명주기 : Android activity lifecycle

시작하기 전에... 본 포스트에서 사용한 코드와 코드랩은 밑의 링크에서 다운 받아 사용할 수 있습니다. 단일 액티비티(MainActivity.kt)로 구성되어 있는 앱입니다. 직접 따라하며 익혀도 되고 빠르

latte-is-horse.tistory.com

참고 자료

https://developer.android.com/guide/fragments/lifecycle#fragmentmanager

 

Fragment lifecycle  |  Android Developers

Fragment lifecycle Each Fragment instance has its own lifecycle. When a user navigates and interacts with your app, your fragments transition through various states in their lifecycle as they are added, removed, and enter or exit the screen. To manage life

developer.android.com

https://developer.android.com/codelabs/kotlin-android-training-lifecycles-logging?index=..%2F..android-kotlin-fundamentals#5 


프래그먼트의 특징

프래그먼트의 뷰는 프래그먼트의 생명 주기와는 독립적으로 관리되는 별도의 생명 주기가 있다.

프래그먼트가 다른 생명 주기로 전환되려면 FragmentManager 라는 것에 추가가 되어야 한다.

FragmentManager은 프래그먼트가 어떤 상태에 있어야 하는지 결정하고, 해당 상태로 이동시키는 역할을 한다.

또한, 생명 주기 외에도 호스트 액티비티에 프래그먼트를 연결하고, 프래그먼트가 더 이상 사용되지 않으면 분리하는 역할도 한다.

(참고로 프래그먼트는 단독으로 실행될 수 없고, 항상 액티비티 위에서 동작하기 때문에 호스트 액티비티가 있어야한다)

주의: 프래그먼트의 생명 주기는 상위의 액티비티나 프래그먼트의 생명 주기보다 앞설 수 없다.
예를 들어, 부모 프래그먼트나 액티비티는 자식 프래그먼트보다 먼저 실행되어야 하고, 자식 프래그먼트는 부모 프래그먼트나 액티비티보다 먼저 정지되어야 한다.
: 위와 같은 상황을 방지하기 위해 XML 파일에 <fragment> 태그로 프래그먼트 대신 <FragmentContainerView> 를 추가하면 된다.

 

프래그먼트의 라이프 사이클

프래그먼트 생명주기, 프래그먼트 콜백 함수, 뷰의 생명 주기

위 그림은 FragmentManager에 프래그먼트가 추가된 이후 생명 주기를 나타낸다. 즉, onAttach() 콜백 함수가 호출된 이후이다.

 

onAttach()

onAttach()

onAttach()는 프래그먼트가 FragmentManager에 추가되고, 호스트 액티비티에 연결 될 때 호출된다.

이 시점에 프래그먼트가 활성화되고, FragmentManager은 프래그먼트의 생명 주기를 관리한다.

또한 이때부터 findFragmentById() 와 같은 메소드로 프래그먼트를 반환할 수 있는 시점이다.

 


다음의 내용들은 프래그먼트가 시작되거나 재개되는 시점에 호출되는 콜백에 대한 내용이다

onCreate()

onCreate()

액티비티의 onCreate()와 비슷하게 초기 프래그먼트 생성을 수행하지만 레이아웃 작업은 여기서 하지 않는다.

 

onCreateView()

onCreateView()

onCreateView() 내부에서 프래그먼트의 레이아웃을 inflate하게 된다.

 

onViewCreated()

onViewCreated()

onViewCreated() 콜백은 onCreateView()가 반환된 이후에 바로 실행되지만 저장된 상태가 뷰에 복원되기 전에 호출된다.

 

onStart()

onStart()

onStart()는 프래그먼트의 뷰 작업이 완료되어 사용자에게 보여지는 시점에 호출된다. 액티비티의 onStart() 와 같다.

이 시점에서 프래그먼트는 STARTED 상태가 된다.

 

onResume()

onResume()

onResume() 은 프래그먼트가 보이고, 전환 효과 등이 끝나고 사용자와 상호 작용 가능한 때에 호출된다. 액티비티의 onResume()과 같다.

이 시점에서 프래그먼트는 RESUMED 상태가 된다.


다음의 내용들은 프래그먼트가 이동하거나 변화가 있을 때 발생하는 콜백에 대한 내용이다

 

onPause()

onPause()

onPause()는 프래그먼트가 포커즈를 잃어 사용자와 상호 작용이 불가해지는 시점에 호출된다. 액티비티의 onPause()와 같다.

이 시점에서 프래그먼트는 STARTED 상태로 돌아간다.

 

onStop()

onStop()은 프래그먼트가 더 이상 보이지 않을 때 호출된다. 액티비티의 onStop()과 같다.

이때 프래그먼트와 뷰의 생명 주기는 CREATED 상태로 변경된다.

 

onDestroyView()

모든 종료 애니메이션과 전환이 완료된 후 뷰가 윈도우와 분리되는 시점에  onDestroyView()가 호출된다.

이 시점에 프래그먼트 뷰에 대한 참조를 제거해야 뷰가 가비지 컬렉터에 의해 수집될 수 있다.

이때 프래그먼트 뷰의 생명 주기는 DESTROYED 상태가 된다.

 


 

상황에 따른 콜백 함수 호출

1. 프래그먼트 최초 실행

프래그먼트 최초 실행

onAttach() -> onCreate() -> onCreateView() -> onViewCreated() -> onStart() -> onResume() 순으로 호출된다.

  1. 최초에 프래그먼트가 호스트 액티비티에 부착되고, FragmentManager에 추가되면서 onAttach()가 호출
  2. 초기화가 이루어지는 onCreate() 호출
  3. 뷰를 inflate 하는 onCreateView() 호출
  4. 뷰가 생성된 시점에 onViewCreated() 호출
  5. 프래그먼트가 사용자에게 보이는 시점에 onStart() 호출
  6. 사용자와 상호 작용 가능한 시점에 onResume() 호출

 

2. 다른 화면(프래그먼트)으로 이동

다른 화면으로 이동

onPause() -> onStop() -> onDestroyView() 순으로 호출된다.

주의할 점은 A -> B로 이동했을 때 B의 로그가 아닌 A의 로그인 점을 헷갈리지 않아야 한다.

  1. 사용자와 상호 작용이 불가해지며 onPause() 호출
  2. 화면에서 보이지 않게 되며 onStop() 호출
  3. 분리된 뷰가 제거되면서 onDestroyView() 호출

 

3. (앱 바의) 위로 버튼을 눌러 되돌아 가는 경우

되돌아가는 경우

onCreateView() -> onViewCreated() -> onStart() -> onResume() 순으로 실행

  1. 프래그먼트가 제거된 것이 아니라 백스택에 유지되어 있었기 때문에 onAttach(), onCreate()가 실행되지 않고 바로 onCreateView()가 실행되어 뷰를 다시 연결
  2. 화면에 표시되는 시점에 onStart() 호출
  3. 사용자와 상호 작용 가능한 시점에 onResume() 호출

 

4. 화면을 닫은 경우 (앱 종료 등)

화면 닫은 경우

onPause() -> onStop() -> onDestroyView() -> onDetach() 순으로 실행

  1. 사용자와 상호 작용 할 수 없는 시점에 onPause() 호출
  2. 화면에 더 이상 보이지 않게 되는 시점에 onStop() 호출
  3. 뷰가 제거되는 시점에 onDestroyView() 호출
  4. 프래그먼트가 FragmentManager에서 제거되고 메모리에서 해제되는 시점에 onDetach() 호출

 


마무리

프래그먼트도 액티비티와 비슷한 생명 주기를 가지고 있다. 하지만 프래그먼트는 액티비티 위에서 동작하는 점과 프래그먼트와 뷰가 각각의 생명 주기를 가진다는 점 등의 차이가 존재하고, 그로 인해 조금 더 세분화된 생명 주기를 가진다.

상태가 저장되고, 인스턴스를 불러오는 등의 내용은 본 포스터의 내용이 너무 복잡해질 것 같아서 제외했다. 앞으로 추가로 공부해봐야 할 부분이다.

요즘은 프래그먼트를 사용하지 않는 앱이 거의 없을 정도로 많이 사용되는 만큼 생명 주기도 제대로 알고 사용하는 것이 좋을 것 같다.

반응형
Comments