활동 상태 변경 처리
사용자가 Activity를 벗어났다가 다시 돌아왔을 때 Activity가 작동하는 방식을
수명 주기 콜백 메서드에서 선언할 수 있습니다.
1. Configuration 변경 발생
구성 변경을 트리거할 수 있는 여러 이벤트가 있습니다.
아마도 가장 눈에 잘 띄는 예는 세로 모드와 가로 모드 간 방향 변경일 것입니다.
구성 변경을 일으킬 수 있는 다른 사례로는 언어 또는 입력 기기 변경이 있습니다.
구성 변경이 발생하면 Activity가 제거되고 다시 생성됩니다.
원래 Activity 인스턴스에서는 onPause(), onStop() 및 onDestroy() 콜백이 트리거됩니다.
그리고 Activity의 새 인스턴스가 생성되고 onCreate(), onStart() 및 onResume() 콜백이 트리거됩니다.
ViewModel, onSaveInstanceState() 메서드 또는 영구 로컬 저장소의 조합을 활용하면 구성 변경 전체에 걸쳐 Activity의 UI 상태를 유지할 수 있습니다.
2. Activity 또는 Dialog가 포그라운드로 나옴
새 Activity 또는 Dialog가 포그라운드로 나옴에 따라 포커스를 얻고 진행 중인 Activity를 부분적으로 가리면 가려진 Activity는 포커스를 잃고 '일시중지됨' 상태로 전환됩니다. 그러면 시스템은 onPause()를 호출합니다. 가려진 Activity가 포그라운드로 돌아와서 포커스를 다시 얻으면 시스템은 onResume()을 호출합니다.
새 Activity 또는 Dialog가 포그라운드로 나옴에 따라 포커스를 얻고 진행 중인 Activity를 완전히 가리면 가려진 Activity는 포커스를 잃고 '중지됨' 상태로 전환됩니다. 그러면 시스템은 onPause() 및 onStop()을 빠르게 연속적으로 호출합니다. 가려진 Activity의 동일한 인스턴스가 포그라운드로 다시 돌아오면 시스템은 onRestart(), onStart() 및 onResume()을 호출합니다. 인스턴스가 백그라운드로 전환된 가려진 Activity의 새 인스턴스이면 시스템은 onRestart()를 호출하지 않고 onStart() 및 onResume()만 호출합니다.
3. 사용자가 뒤로 버튼을 탭함
Activity가 포그라운드에 있는데 사용자가 뒤로 버튼을 탭하면 Activity는 onPause(), onStop() 및 onDestroy() 콜백을 거치며 전환됩니다. 이때, Activity는 제거될 뿐만 아니라 백 스택에서도 삭제됩니다.
이런 상황에서는 기본적으로 onSaveInstanceState() 콜백이 실행되지 않는다는 점에 유의해야 합니다. 이 동작은 사용자가 Activity의 동일한 인스턴스로 돌아올 것으로 예상하지 않고 뒤로 버튼을 탭했다는 가정을 기반으로 합니다. 그러나 onBackPressed() 메서드를 재정의하면 'confirm-quit' 대화상자와 같은 일부 맞춤 동작을 구현할 수 있습니다.
onBackPressed() 메서드를 재정의할 때는 재정의한 메서드에서 super.onBackPressed()를 호출하는 것이 좋습니다. 호출하지 않으면 뒤로 버튼 동작이 사용자에게 부자연스럽게 보일 수 있습니다.
UI 상태 저장 및 복원
Activity의 추가적인 인스턴스 상태 정보를 저장하려면 onSaveInstanceState()를 재정의하고, Activity가 예상치 못하게 소멸될 경우 저장되는 Bundle 객체에 키-값 쌍을 추가해야 합니다. 이는 onStop() 다음에 호출되지만 사용자가 Activity를 명시적으로 닫는 경우 또는 finish()가 호출된 경우에는 onSaveInstanceState()가 호출되지 않습니다.
override fun onSaveInstanceState(outState: Bundle) {
// Save the state what you want to save
outState?.run {
putInt(STATE_INT, valueInt)
putBoolean(STATE_BOOLEAN, valueBoolean)
}
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(outState)
}
Activity가 이전에 소멸된 후 재생성되면, 시스템이 활동에 전달하는 Bundle로부터 저장된 인스턴스 상태를 복구할 수 있습니다. onCreate() 및 onRestoreInstanceState() 콜백 메서드 둘 다 인스턴스 상태 정보를 포함하는 동일한 Bundle을 수신합니다.
onCreate() 메서드는 시스템이 Activity의 새 인스턴스를 생성하든, 이전 인스턴스를 재생성하든 상관없이 호출되므로 읽기를 시도하기 전에 Bundle 상태가 null인지 반드시 확인해야 합니다. null일 경우, 시스템은 이전에 소멸된 Activity의 인스턴스를 복원하지 않고 새 인스턴스를 생성합니다.
override fun onCreate(savedInstanceState: Bundle?) {
// Always call the superclass first
super.onCreate(savedInstanceState)
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
with(savedInstanceState) {
// Restore value of members from saved state
valueInt = getInt(STATE_INT)
valueBoolean = getBoolean(STATE_BOOLEAN)
}
} else {
// Probably initialize members with default values for a new instance
}
// ...
}
onCreate() 중에 상태를 복원하는 대신 onRestoreInstanceState()를 사용할 수 있는데 이는 onStart() 다음에 호출됩니다. 시스템은 복원할 저장 상태가 있을 경우에만 onRestoreInstanceState()를 호출하기 때문에 Bundle 상태가 null인지 확인할 필요가 없습니다.
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState)
// Restore state members from saved instance
savedInstanceState?.run {
valueInt = getInt(STATE_INT)
valueBoolean = getBoolean(STATE_BOOLEAN)
}
}
'안드로이드 > 개념' 카테고리의 다른 글
[Android] Serializable vs Parcelable (0) | 2023.07.21 |
---|---|
[Android] Timer와 Thread (0) | 2023.07.18 |
[Android] 명시적 인텐트와 암시적 인텐트 (0) | 2023.07.16 |
[Android] Android의 이해 (0) | 2023.07.15 |
[Android] Kotlin의 이해 (0) | 2023.07.15 |