본문 바로가기
Android/기타

생명주기에 대해서

by 안스 인민군 2022. 11. 3.

생명주기(Lifecycle)

1) 생명주기란 무엇인가?

Lifecycle은 Life + cycle의 합성어로, 삶의 순환이라고 직역할 수 있겠다. 말 그대로 탄생하고 성장하여 죽음에 이르기까지의 과정이라고 생각한다면, 이것을 안드로이드 앱에 적용한 것이 바로 Android Lifecycle이다. Activity, Fragment, Service 총 세가지 종류의 Lifecycle이 있으며 오늘은 그 중 Activity의 Lifecycle에 대해서만 포스팅하도록 하겠다.

2) 생명주기가 필요한 이유

예를 들어보자. 당신은 지금 여자친구와 카톡을 하고 있다. 그런데 갑자기 친구가 술먹자며 나오라고 전화를 했다. 당신이 전화를 받는순간 전화창이 화면에 보일 것이다. 그러다 약속을 잡고 전화를 끊고 다시 카톡을 실행하면 화면에 카톡창이 보일 것이다.

위 예시를 보자.
카톡 실행중 -> 카톡 닫고 전화 실행 -> 전화 실행중 -> 전화 끊고 카톡 실행 -> 카톡 실행중
위와 같은 로직이 나오게 된다. 사용자들은 그저 실행과 종료를 통해 해당 로직을 파악할 수 있지만, 우리의 안드로이드는 그러지 못한다. 그렇기에 Lifecycle이라는 개념을 넣어 안드로이드 프로그램의 상태 변화를 파악하고 반응할 수 있게 한 것이다.

액티비티 생명주기(Activity Lifecycle)

위 사진은 안드로이드 4대 컴포넌트 중 하나인 Activity의 Lifecycle 순서도이다.

 

안드로이드는 앱이 실행된 후 다른 액티비티 화면으로 전환되거나, 스마트폰 화면이 꺼지거나 혹은 앱이 종료될 때와 같이 상태 변화가 있을 때마다 화면에 보이는 액티비티의 생명 주기 메서드를 호출해서 상태 변화를 알려준다.

생명 주기 메서드


1) onCreate()

  • Activity가 생성되면 가장 먼저 호출됨
  • 화면 Layout 정의, View 생성, Databinding 등은 이곳에 구현함
  • 생명주기 통틀어서 단 한 번만 수행되는 메소드
  • 따라서 Activity 최초 실행에 해야하는 작업을 수행하기에 적합함

2) onStart()

  • Activity가 화면에 표시되기 직전에 호출됨
  • 화면에 진입할 때마다 실행되어야 하는 작업을 이곳에 구현함

3) onResume()

  • Activity가 화면에 보여지는 직후에 호출됨
  • 현재 Activity가 사용자에게 포커스인 되어있는 상태

4) onPause()

  • Activity가 화면에 보여지지 않은 직후에 호출됨
  • 현재 Activity가 사용자에게 포커스아웃 되어있는 상태
  • 다른 Activity가 호출되기 전에 실행되기 때문에 무거운 작업을 수행하지 않도록 주의해야함
  • 영구적인 Data는 이곳에 저장

5) onStop()

  • Activity가 다른 Activity에 의해 100% 가려질 때 호출되는 메소드
  • 홈 키를 누르는 경우, 다른 액티비티로의 이동이 있는 경우가 있음
  • 이 상태에서 Activity가 호출되면, onRestart() 메소드가 호출됨

6) onDestroy()

  • Activity가 완전히 종료되었을 때 호출되는 메소드
  • 사용자: finish(), onBackPressed()(기존 액티비티의 onResume()까지 호출된 후 onDestroy() 호출)
  • 시스템: 메모리부족(프로세스 종료)
  • onStop(), onDestroy() 메소드는 메모리 부족이 발생하면 스킵될 수 있음

7) onRestart()

  • onStop()이 호출된 이후에 다시 기존 Activity로 돌아오는 경우에 호출되는 메소드
  • onRestart()가 호출된 이후 이어서 onStart()가 호출됨

Fragment 생명주기

 

1. onAttach()

  • 프래그먼트가 액티비티에 붙을 때 호출
  • 인자로 Context가 주어진다. 그러므로 Fragment에서 context가 필요하다면 여기서 꺼내쓰면 된다.

2. onCreate()

  • 프래그먼트가 액티비티의 호출을 받아 생성
  • Bunddle로 액티비티로부터 데이터가 넘어옴
  • UI 초기화는 불가능

3. onCreateView()

  • 레이아웃 inflate 담당
  • savedInstanceState로 이전 상태에 대한 데이터 제공
  • View와 관련된 객체를 초기화 할 수 있음

4. onViewCreated()

  • onCreagteView()를 통해 반환된 View 객체는 onViewCreated()의 파라미터로 전달 된다.
  • 이 때 Lifecycle이 INITIALIZED 상태로 업데이트가 됨
  • 때문에 View의 초기값 설정, LiveData 옵저빙, RecyclerView, ViewPager2에 사용될 Adapter 세팅은 이 메소드에서 해주는 것이 적절함

5. onViewStateRestored()

  • 저장해둔 모든 state 값이 Fragment의 View의 계층 구조에 복원되었을 때 호출 ex) 체크박스 위젯이 현재 체크되어있는가
  • View lifecycle owner : INITIALIZED → CREATED 변경

6. onStart()

  • 사용자에게 보여질 수 있을 때 호출
  • Activity의 onStart() 시점과 유사
  • Fragment의 childFragmentManager을 통해 FragmentTransaction을 안전하게 수행할 수 있음
  • View lifecycle owner : CREATED → STARTED 변경

7. onResume()

  • 사용자와 프래그먼트가 상호작용 할 수 있는 상태일 때 호출
  • Fragment가 보이는 상태에서 모든 Animator와 Transition 효과가 종료되고, 프래그먼트와 사용자가 상호작용 할 수 있을 때 onResume Callback

8. onPause()

  • Fragment가 visible 일 때 onPause()가 호출
  • 이 때 Faragment와 View의 Lifecycle이 PAUSED가 아닌 STARTED가 됨

9. onStop()

  • Fragment가 더 이상 화면에 보여지지 않게 되면 onStop() 콜백 호출
  • 부모 액티비티, 프래그먼트가 중단될 때, 상태가 저장될 때 호출
  • View와 Lifecycle : STARTED  CREATED
  • API 28버전을 기점으로 onSaveInstanceState() 함수와 onStop() 함수 호출 순서가 달라짐, 따라서 onStop()이 FragmentTransaction을 안전하게 수행하는 마지막 지점이 됨

10. onDestoryView()

  • 모든 exit animation, transaction이 완료되고 Fragment가 화면으로부터 벗어났을 경우 호출
  • view와 lifecycle : CREATED → DESTROYED
  • 가비지 컬렉터에 의해 수거될 수 있도록 Fragment View에 대한 모든 참조가 제거되어야 함
  • getViewLifecycleOwnerLiveData()

11. onDestroy()

  • Fragment가 제거되거나, FragmentManager가 destroy 됐을 경우, onDestroy() 콜백 함수가 호출
  • Fragment Lifecycle의 끝을 알림

12. onDetach()

  • 프래그먼트가 액티비티로부터 해제되어질 때 호출된다.

Viewmodel의 생명주기

Configuration 변경이 (예:화면 회전) 발생할 때 액티비티가 다시 시작 되는 것을 확인할 수 있다. 하지만 ViewModel은 여전히 메모리 상에 남아있는다. 이는 Activity 내부에서 Configuration 변경과 무관하게 유지 되는 NonConfigurationInstances 객체를 따로 관리하기 때문이다.

Activity의 finish() 호출등에 의해 액티비티가 생명주기가 종료됨에 따라 내부의 LifecycleEventObserver를 통해 ViewModel도 onCleared() 콜백 메서드를 호출하고 종료된다.