액티비티와 프래그먼트는 시작되고 종료되는 시점까지 각각의 생명주기 즉, Activity Lifecycle, Fragment Lifecycle을 갖는다. 이 주기 안에서 액티비티와 프래그먼트는 각각의 상태가 계속해서 바뀌게 된다.
예를 들어, 안드로이드 앱이 실행된 후 다른 화면으로 전환되거나, 화면이 꺼짐, 폰 상태바를 내려서 화면이 가려짐, 혹은 앱이 종료될 때 등의 상황에서 상태 변화가 일어난다.
안드로이드 프레임워크에서는 액티비티/프래그먼트의 상태가 변화할 때마다 특정 동작을 수행할 수 있도록 여러 콜백 메서드를 제공한다. 이를 Lifecycle Callback Method라고 하며, 콜백 메서드의 구현을 통해 상태 변화로 일어나는 다양한 문제를 예방하고 앱이 보다 안정적으로 동작하게 할 수 있다.
Activity Lifecycle
Activity Lifecycle의 콜백함수에는 onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy(), onRestart()가 존재한다. 아래는 액티비티 생명주기를 시각적으로 나타낸 다이어그램이다.

onCreate()
• 시스템이 액티비티를 생성할 때 실행되는 콜백함수
• 다른 콜백 메서드들과 다르게 필수적으로 오버라이딩 하여 구현해야 함
• 액티비티 전체 생명주기 동안 딱 한 번만 동작되기 때문에 초기화 및 시작 로직을 구현함 (ex. RecyclerView에 데이터를 바인딩한다든가, 버튼에 View.OnClickListener 를 설정하는 등의 동작)
onCreate()는 savedInstanceState라는 파라미터를 수신하는데, 이는 액티비티의 이전 상태가 저장된 Bundle 객체에 해당된다. (처음 생성된 액티비티인 경우 null을 담고 있음) 이를 통해 이전 상태를 복원하여 화면에 표시할 수 있다.
onCreate() 의 동작이 끝났다고 해서 액티비티가 종료되는 것이 아니고, 액티비티가 'STARTED' 상태에 진입하게 되어 시스템은 onStart() 와 onResume()을 연달아 호출하게 된다.
onStart()
• 액티비티가 STARTED 상태에 진입하게 되면 호출됨
• 액티비티가 사용자에게 보여지기 직전 상태로, 액티비티를 포그라운드에 보내 사용자와 상호작용할 수 있도록 준비함 (ex. UI를 관리하는 코드를 초기화하는 동작)
onStart() 는 매우 빠른 속도로 실행되고, 액티비티가 'RESUMED' 상태에 진입함과 동시에 onResume() 메서드를 호출하게 된다.
onResume()
• 포그라운드에 액티비티가 표시되고 앱이 사용자와 상호작용을 할 수 있는 상태가 됨
• 어떤 방해 이벤트 및 인터럽트(전화가 오거나 화면을 슬립하는 등 이벤트)가 발생하여 사용자의 포커스가 없어지지 않는 이상, 앱은 'RESUMED' 상태에 계속 머무르게 됨
• 방해가 되는 이벤트가 발생하면 액티비티는 'PAUSED' 상태에 들어가고, 시스템이 onPause() 메서드를 호출함
전화를 다 받고 오는 등, 액티비티가 다시 화면에 보여지면서 'RESUMED' 상태로 돌아오게 되면 시스템이 다시 한 번 onResume() 메서드를 호출하게 된다. 따라서, onResume()을 구현하여 onPause() 중에 해제되는 구성요소를 다시 초기화하고, 액티비티가 재개될 때마다 필요한 이외 초기화 작업을 수행하면 된다.
onPause()
• 사용자가 잠시 액티비티를 떠났을 때 (다른 액티비티에 포커스를 뒀을 때) 호출되는 콜백함수
• 해당 액티비티가 포그라운드에 있지 않게 되었다는 것을 의미함
• 액티비티가 포그라운드에 없을 동안 계속 실행되어서는 안 되지만 언젠가 다시 시작할 작업을 일시중지하는 작업을 수행함
• onPause() 메서드를 사용하여 배터리 수명에 영향을 미칠 수 있는 모든 시스템 리소스, 하드웨어 센서 등을 할당 해제하면 자원을 효율적으로 사용할 수 있음
onPause()는 아주 잠깐 실행되기 때문에 무언가를 저장하는 작업을 실행하기엔 시간이 부족할 수 있다. 따라서 onPause() 내에서는 사용자 데이터 저장, 네트워크 호출, DB 트랜잭션 등을 실행해서는 안 된다. 이렇게 부하가 큰 작업들은 onStop()에서 수행해야 한다.
액티비티가 다시 시작되거나, 사용자에게 완전히 보여지지 않는 이상 액티비티는 'PAUSED' 상태에 머무르게 된다. 이 때 다시 액티비티가 재개되면 메모리 상 남아있던 액티비티 인스턴스를 다시 불러와 onResume() 메소드를 호출한다.
onStop()
• 액티비티에서 포커스가 완전히 제거되었을 때 시스템에서 호출되는 콜백 메서드 (ex. 화면 전체가 가려졌을 때 또는 백그라운드로 갔을 때)
• 해당 메서드에서 필요하지 않은 리소스를 해제하거나 조정해야 함 (ex. 애니메이션을 일시중지하거나, GPS 사용 시 배터리를 아끼기 위해 위치 인식 정확도를 '세밀한 위치'에서 '대략적인 위치'로 전환하는 작업)
• CPU 를 비교적 많이 소모하는 작업을 종료해야 함 (ex. 어떠한 정보를 DB 에 저장하는 작업)
액티비티가 'STOPPED' 상태에 들어가더라도 액티비티 객체는 메모리 안에 머무른다. 그런데 시스템이 더 우선순위가 높은 프로세스를 위해 메모리를 확보해야하는 경우, 이 액티비티를 메모리 상에서 죽이게 된다.
하지만 그럼에도 Bundle에 View 객체 상태를 그대로 저장해두고, 사용자가 이 액티비티로 다시 돌아오게 되면 이를 기반으로 상태를 복원한다.
만약 사용자가 다시 액티비티로 돌아오게 되면, 'STOPPED' 상태에서 다시 시작되어 onRestart() → onStart() → onResume()이 연달아 호출되며 'RESUMED' 상태로 변화하여 다시 포그라운드 액티비티로써의 태스크를 시작하며 사용자와 상호작용을 시작한다.
onDestroy()
• 액티비티가 완전히 소멸되기 전에 호출되는 콜백 함수
액티비티가 완전히 소멸되는 경우는 아래와 같은데,
- finish() 가 호출되거나 사용자가 앱을 종료하여 액티비티가 종료되는 경우
- 화면 구성이 변경되어 (기기 회전 등) 일시적으로 액티비티를 소멸시키는 경우
액티비티가 종료되는 경우 onDestroy() 가 마지막 라이프사이클 콜백 메서드가 된다. 만약 위의 2번 사유로 인해 호출된 거라면, 시스템이 즉시 새롭게 변경된 액티비티 인스턴스를 생성하여 onCreate()를 호출한다.
만약 onDestroy()가 호출되기 까지 해제되지 않은 리소스가 있다면, 모두 여기서 해제해줘야 한다.
Memory Leak(메모리 누수) 의 위험이 있다.
onRestart()
• 'STOPPED' 상태에 있던 화면에 다시 접근했을 때 호출되는 콜백함수
Fragment Lifecycle
Fragment LifeCycle의 콜백함수에는 onAttach(), onCreate(), onCreateView(), onActivityCreated(), onStart(), onResume(), onPause(), onStop(), onDestroyView(), onDestroy(), onDetach()가 존재한다.

onAttach()
• 액티비티에서 프래그먼트가 호출될 때 최초 한 번 호출되는 콜백함수
• 아직 프래그먼트가 완벽하게 생성된 상태는 아니며, 인자로 Context가 주어짐
onCreate()
• 프래그먼트가 액티비티의 호출을 받아 생성될 때 호출되는 콜백함수
• 해당 콜백함수에서 리소스를 초기화함 (UI 초기화는 불가능)
• Bunddle로 액티비티로부터 데이터가 넘어옴
onCreateView()
• 프래그먼트의 뷰를 생성하는 콜백함수
• 프래그먼트에서 UI를 그릴 때 호출되는 콜백함수로, View 객체를 얻을 수 있으므로 프래그먼트에 속한 각종 view나 viewGroup에 대한 초기화 작업을 수행함 (ex. 버튼이나 텍스트뷰의 ui 바인딩 작업을 수행)
• 매개변수인 savedInstanceState로 프래그먼트가 재개되는 경우 이전 상태에 대한 데이터를 제공함 (추가 설명 필요)
onActivityCreated()
• 프래그먼트에서 onCreateView를 마치고 액티비티에서 onCreate가 호출되고 나서 호출되는 콜백함수
• 액티비티에서 프래그먼트를 모두 생성하고 난 다음에 호출됨
• 액티비티와 프래그먼트의 뷰가 모두 생성된 상태로, View를 변경하는 작업이 가능한 단계
• 액티비티와 프래그먼트가 연결되는 시점이며, Activity와 Fragment의 뷰가 모두 생성되고, 연결된 상태임
onViewStateRestored()
• 저장해둔 모든 state 값이 프래그먼트의 view 계층 구조에 복원되었을 때 호출됨 (ex. 체크박스 위젯이 현재 체크되어 있는지 확인하는 작업)
onStart()
• 프래그먼트가 사용자에게 보여지기 전에 호출되는 콜백함수
• 사용자에게 프래그먼트가 보이도록 해줌
• 액티비티와 같이 프래그먼트가 화면에 보여지기 직전 빠르게 실행됨
• 여기서 액티비티는 'STARTED' 상태임
onResume()
• 프래그먼트가 비로소 화면에 보여지는 단계
• 사용자에게 포커스를 잡은 상태로 사용자와의 상호작용이 가능함
• 액티비티와 마찬가지로 이벤트가 발생하여 프래그먼트가 가려지기 전까지 이 상태가 유지됨
onPause()
• 해당 콜백함수가 호출되면 프래그먼트는 사용자와의 상호작용을 중지함
• 부모 액티비티가 아닌 다른 액티비티가 위로 올라오거나, 다른 프래그먼트가 add 되는 경우 'PAUSED' 상태로 들어감
• UI 관련 처리를 정지하고, 중요한 데이터를 저장함
onStop()
• 프래그먼트는 더 이상 보여지지 않게 되며, 프래그먼트 기능이 중지될 때 호출됨
• Fragment가 완전히 가려지는 경우, onPause()에 이어 onStop()까지 호출됨
• 시스템에서 onStateInstance()를 호출하여 UI의 상태를 저장하므로 액티비티를 다시 띄우면 이전 상태가 그대로 보여짐
onDestroyView()
• 프래그먼트와 관련된 view가 제거될 때 호출됨
• 액티비티에서 프래그먼트 생성 시 addToBackStack()를 요청했을 경우 onDestroy()를 호출하지 않고 인스턴스가 저장되어 있다가 프래그먼트를 다시 부를 때 onCreateView()를 실행하여 다시 화면에 보여지게 함
• 가비지 컬렉터에 의해 수거될 수 있도록 Fragment View에 대한 모든 참조가 제거되어야 함
onDestroy()
• view가 제거된 후 프래그먼트가 완전히 소멸되기 전에 호출됨
• 프래그먼트 생명주기의 끝을 알림
onDetach()
• 프래그먼트가 완전히 소멸되고 액티비티와의 연결도 끊어질 때 호출됨
(추가 설명 필요)