2021.11.12에 수정
Lifecycle이란?
안드로이드의 컴포넌트는 Lifecycle을 가지고 있습니다.
Lifecycle은 컴포넌트가 생성되고 사라지기 전까지 갖게되는 상태의 집합입니다.
컴포넌트는 사용자가 앱을 사용하면서 일어나는 상황에따라 다른 상태로 전환되고, 전환될때마다 안드로이드 시스템은 Lifecycle 콜백을 호출해서 컴포넌트에게 상태 전환을 알려줍니다.
사용자가 기대하는 방식으로 앱이 작동할 수 있도록 라이프사이클 콜백이 호출되는 시기와 각 콜백 메서드에서 수행해야할 작업을 이해하고, Lifecycle 콜백 메서드를 구현해야합니다.
안드로이드 컴포넌트
- 안드로이드 컴포넌트에는 Activity, Fragment, Service, App 자체, 기본 프로세스가 될 수 있습니다.
onCreate()
- Activity가 시작될 때 호출됩니다.
onCreate()의 기본 구현
- 구성 변경으로 액티비티를 재생성하거나, 리소스 부족으로 메모리를 복구하기 위해 액티비티를 제거해 나중에 액티비티가 재생성되어야할 때, 유저가 액티비티를 종료한것이 아니기때문에 이전과 같은 UI 상태를 기대합니다. savedInstanceState의 데이터로 이전 UI 상태를 복구합니다.
- 구성 변경
- 기기 회전, 창 크기 조정
- savedInstanceStateex) EditText에 입력된 텍스트 값, ListView의 스크롤 위치
- onSaveInstanceState()에서 저장된 액티비티 레이아웃의 각 View에 대한 정보가 제공됩니다.
- 액티비티가 처음 시작되는경우, 유저가 뒤로가기를 누르거나 finish()가 호출되는것과 같이 액티비티가 더이상 필요하지 않아서 제거되었다가 나중에 액티비티가 다시 시작되는경우에 savedInstanceState는 null이고 복원 작업을 수행하지 않습니다
onCreate에서 하는 작업
- setContentView
- LayoutInflater로 레이아웃 xml 파일을 view 객체로 생성합니다.
- 윈도우에 뷰를 배치합니다.
- 액티비티가 시작될 때 한번만 호출되는 콜백이므로 여기서 멤버변수 초기화, 데이터바인딩을 생성하고 뷰와 연결하는 작업을 정의합니다.
- savedInstanceState
- 기본 UI 복원 외에 필요하다면 onSaveInstanceState()에서 직접 저장한 데이터를 복원하는 작업을 수행할 수 있습니다.
onStart()
- onCreate() 다음에 호출되거나 onRestart() 다음에 호출됩니다.
onStart의 기본 구현
- UI를 관리하는 코드를 초기화합니다.
onStart()에서 하는 작업
- onCreate()에서 초기화했던 객체들의 작업을 시작합니다. onStart()에서 작업을 시작하면 onStop()에서 작업을 중지해야합니다. 중지하지 않으면 작업이 여러번 등록 될 수 있습니다. (ex 브로드캐스트 리시버)
- 데이터바인딩이 바인딩을 시작합니다.
onRestart()
- 유저가 홈으로 이동하거나, 전화, 문자, 알림 확인 등으로 다른 앱에게 현재 액티비티가 완전히 가려져서 Stopped 상태가 되었다가 (액티비티가 시스템에 의해 제거되지 않고) 다시 액티비티로 돌아오는경우 onRestart()가 호출됩니다.
- onPause() → 다른 액티비티가 생성되어 액티비티가 가려짐 → onStop() → 액티비티가 다시 포그라운드로 돌아옴 → onRestart()
onRestoreInstanceState()
- 액티비티가 재생성되어 복원되어야하는 경우에만 onStart() 다음에 onRestoreInstanceState()가 호출됩니다.
- onCreate() → onStart() → onRestoreInstanceState()
- onCreate()와 달리 savedInstanceState이 null인지 확인할 필요가 없습니다.
- 복원 로직을 보강하거나 대체할 수 있습니다.
onResume()
- 액티비티가 Resumed 상태가 되면 액티비티는 포그라운드로 이동하고 안드로이드 시스템은 onResume을 호출합니다.
- 포그라운드
- 안드로이드 시스템은 포그라운드 앱과 백그라운드 앱을 구분합니다. 액티비티가 사용자에게 보이고 상호작용할 수 있는 상태일때 액티비티가 포그라운드에 있다라고 할 수 있습니다.
- 액티비티가 보인다고 하더라도 사용자와 상호작용하지 못하면 앱이 백그라운드에 있는 상태입니다.
- 포그라운드
- onResume 호출 시부터 유저와 UI 상호작용을 허용합니다. 하지만 준비되지않은 뷰는 화면에 아직 그려지기전일수도 있습니다. UI는 액세스할 준비와 유저와 상호작용할 준비가 완료되면 화면에 그려집니다.
- 앱에서 포커스를 잃는 일이 발생할 때까지 액티비티는 Resumed 상태를 유지합니다.
- 포커스를 잃는것과 같은 중단 이벤트가 발생하면 시스템은 onPause() 콜백을 호출합니다. 이후 다시 Resumed 상태로 돌아올수 있으므로 onPause() 중에 해제하는 구성 요소를 초기화하고, resumed 상태에서 발생해야 초기화를 수행해야 합니다.
onPause()
- 액티비티가 포커스를 잃거나 종료될때 onPause()가 호출됩니다.
- 다른 앱의 dialog가 보여져서 액티비티가 일부 가려진 경우에는 Pause 상태를 유지합니다. ex) 알람, 전화
- 새 액티비티가 시작되어 이전 액티비티가 완전히 가려진 경우에는 onPause() → onStop() 가 순서대로 호출되고 Stopped 상태를 유지합니다.
- 액티비티가 종료하는 경우에는 onPause() → onStop() → onDestroy() 가 순서대로 호출됩니다.
- 계속 실행되어서는 안되지만 잠시 멈춘 후 다시 시작할 작업을 일시정지하거나, 리소스를 해제합니다. 이때 시간이 오래 걸리는 작업은 onPause()에서 하지않고 onStop()에서 합니다. 또한 Pause 상태에서는 액티비티가 일부 보일수도 있으니 UI 관련 리소스를 완전히 해제하는 것도 onStop에서 합니다.
- ex) 브로드캐스트 리시버 레지스터를 onStart() 에서 했다면 onPause에서 언레지스터 해줍니다.
- 시간이 오래 걸리는 작업
- 데이터 저장, 네트워크 호출, 데이터베이스 트랜잭션의 작업을 하지 않습니다.
onStop()
- 액티비티가 완전히 가려지는 경우에 onPause() 호출 다음에 onStop()이 호출되고 Stopped 상태를 유지합니다.
- 유저가 뒤로가기를 누르거나, finish()가 호출되어 액티비티가 제거되는 경우에 순서대로 onPause() → onStop() → onDestroy() 가 호출됩니다.
- 액티비티가 제거되지 않았지만 window manager와 연결되지는 않습니다.
- CPU를 많이 사용하는 작업을 수행합니다. 필요하지 않은 리소스를 해제하거나 조정합니다.
- ex. 애니메이션 일시중지, 세밀한 위치업데이트에서 대략적인 위치업데이트로 전환, 데이터베이스에 저장
onSaveInstanceState()
- 액티비티를 명시적으로 종료하는 경우가 아니라 나중에 재생성될 경우를 대비해 onStop() 호출 후, 현재 UI 상태를 저장하기 위해 호출됩니다.
- 액티비티가 완전히 가려져 Stopped 상태가 되면 시스템이 액티비티를 제거할수도 있기 때문에 onSaveInstanceState()가 항상 호출되지만, 제거되지 않고 액티비티가 돌아오는 경우에는 onRestoreInstanceState()가 호출되진 않습니다.
- onSaveInstanceState()에서는 데이터를 직렬화해 disk에 저장합니다.
- 저장한 데이터는 onCreate()와 onRestoreInstanceState()에서 파라미터 Bundle 객체로 제공됩니다.
- 직렬화하는 개체가 복잡하면 많은 메모리를 소모합니다. 메인 스레드에서 작업하기 때문에 프레임 손실이나 시각적 끊김이 생길수 있습니다.
- 비트맵, 긴 직렬화, 역직렬화가 필요한 복잡한 데이터 구조 X
- primitive 타입이나 String 같은 작은 객체 O (ex. 가장 최근의 검색어)
onDestroy()
- 액티비티가 소멸되기 전에 호출됩니다.
- 시스템이 onDestroy 를 호출하는 2가지 시나리오
- 활동이 종료
- 사용자가 액티비티를 완전히 닫았을때
- 액티비티에서 finish 호출이 되었을때
- 구성 변경으로 시스템이 기존 액티비티를 소멸시키고 새로 다시 생성시키는 경우
- 기기 회전 or 멀티 윈도우 모드
- → isFinishing() 메서드로 구분할 수 있다.
- 활동이 종료
- 액티비티의 수명주기를 수신하는 요소들은 액티비티가 Destroy 상태가 되면 종료를 인식하고 작업을 정리합니다.
시나리오
앱이 종료되고 다시 시작할때 라이프 사이클
- 시나리오
- 유저가 뒤로가기 버튼을 눌러서 액티비티가 종료되는 경우
- 액티비티에서 finish 메서드가 호출되어 종료되는 경우
- 라이프사이클 콜백 메서드 호출 순서
- onCreate → onStart → onResume → 종료 → onPause → onStop → onDestroy → 이후 액티비티 재시작 → onCreate(null) → onStart → onResume
유저가 다른 곳으로 이동
- 시나리오
- 유저가 홈으로 이동
- 새 액티비티가 시작되어 완전히 가려짐
- 라이프사이클 콜백 메서드 호출 순서
- onCreate → onStart → onResume → 다른 곳으로 이동 → onPause → onStop → onSaveInstanceState → 이후 액티비티 다시 접속 → onRestart → onStart → onResume
구성 변경, 시스템에 의해 제거되고 재생성
- 시나리오
- 회전, 창크기 조절과 같은 구성 변경
- Stopped 상태로 백그라운드에 있던 앱이 시스템에 의해 종료되었다가 다시 액티비티 생성
- 라이프사이클 콜백 메서드 호출 순서
- onCreate() → onStart() → onResume() → 액티비티 종료 → onPause() → onStop() → onSaveInstanceState() → onDestroy() → 액티비티 재생성 → onCreate(Bundle) → onStart() → onRestoreInstanceState(Bundle) → onResume()
액티비티 일시중지
- 시나리오
- 다른 액티비티가 기존 액티비티를 일부 가리고, 다른 액티비티에게 포커스를 뺏긴 경우 (ex. 다른 앱의 dialog)
- 멀티 윈도우에서 포커스 상실하는 경우
- 라이프사이클 콜백 메서드 호출 순서
- onCreate → onStart → onResume → 이벤트 → onPause → 포커스가 다시 돌아와 사용자와 상호작용 가능한 상태가 됨 → onResume
startActivity
- 시나리오
- 다른 액티비티가 시작해서 두 액티비티의 라이프사이클이 전환됩니다.
- 라이프사이클 콜백 메서드 호출 순서
- [A]onPause → [B]onCreate → [B]onStart → [B]onResume → [A]onStop
- A의 onStop은 B가 resume 까지 준비가 다 된 뒤에 호출됩니다.
'Android' 카테고리의 다른 글
안드로이드 신입 과제 면접 회고 (0) | 2023.05.06 |
---|---|
[Glide] 이미지 로딩 시 자동으로 이루어지는 다운 샘플링 (0) | 2022.08.10 |
인텐트 필터 작성하고 테스트해보기 (0) | 2021.11.27 |
Android Task (0) | 2021.11.14 |
Android MVP 아키텍처 (0) | 2021.10.30 |