Android Fragment 생명주기와 savedInstanceState 문제 해결 기록
Android Fragment 생명주기와 savedInstanceState 문제 해결 기록
문제 상황
고등학교 때 학교 학우들을 위한 편의 앱 동천 알리미를 만들었다. 시간표, 급식, 공지사항 등을 볼 수 있는 앱이었다.
화면 구성은 다음과 같았다.
- FrameLayout에 4개의 Fragment를 올려놓고
- Bottom Navigation Bar로 show/hide 해서 전환
그런데 버그가 발생했다. 잠깐 다른 앱을 켰다가 다시 돌아오면, hide 해뒀던 Fragment들이 의도와 다르게 show 상태로 바뀌는 경우가 있었다.
디버깅 과정
이 문제 때문에 시간을 많이 썼다. 기억으로는 2주 정도 걸렸다.
- 코드를 한 줄씩 확인했지만 원인을 찾지 못했다
- FragmentManager 동작을 의심해 보기도 했다
- 영어, 중국어, 일본어 문서까지 확인했다
원인 발견
결국 Android 개발 문서에서 답을 찾았다.
일시적으로 앱에서 다른 앱으로 전환했다가 다시 앱으로 돌아왔을 때 시스템은 애플리케이션의 프로세스를 소멸시킬 수 있습니다.
savedInstanceState 때문이었다.
메모리가 부족하면 시스템이 백그라운드 앱의 프로세스를 종료할 수 있다. 이때 Fragment 상태가 savedInstanceState에 저장되는데, show/hide 상태를 직접 관리하던 로직이 이 과정에서 초기화됐다.
해결
Fragment의 상태를 savedInstanceState에 저장하고 복원하는 로직을 추가했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("currentFragment", currentFragmentIndex);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
currentFragmentIndex = savedInstanceState.getInt("currentFragment", 0);
// 해당 Fragment만 show하고 나머지는 hide
}
}
정리
- Android 생명주기를 안다고 생각한 것과 상태 저장, 복원까지 포함해서 이해한 것은 달랐다
- 내 코드에 문제가 없다고 가정하기보다, 플랫폼이 어떤 상황에서 무엇을 보장하고 복원하는지부터 확인하는 편이 빠를 때가 많다
- 결국 가장 신뢰할 수 있는 근거는 공식 문서였다
프로젝트: 동천 알리미(Android) 관련 링크
- GitHub: Neibce/DongcheonAlimi
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.
