엄코딩의 개발 일지

Fabric [ New Fatal Issue] 가 전송되면 항상 조마조마한게 개발자의 마음...

이번 에러 메세지를 해결하는 과정을 기록해보았습니다.


이번 에러 메세지는 다음과 같습니다.


Fatal Exception: java.lang.illegalStateException

Can not perform this action after onSaveInstanceState


이러한 경우는 테스트할 때 한 번도 본 적이 없는 에러였습니다.

직역을 해보자면,


'onSaveInstanceState 후에 action을 수행할 수 없다'


우선, developer.android.com에서 onSaveInstanceState 메소드에 대해서 살펴보았습니다.

간단하게 보고 지나갔던 기억이 있었는데, 다시 보니 중요한 내용이 많았습니다.


이 문제를 해결하면서 중요하다고 생각하는 부분을 정리해 보았습니다.

( 안드로이드 공식 가이드 문서 참고 )


정상적인 앱 동작으로 인해 액티비티가 소멸되는 경우로,

  • 사용자가 Back 버튼을 누르는 경우

  • 액티비티가 finish() 를 호출하여 자체적인 소멸 신호를 보내는 경우

  • 액티비티가 현재 정지되어 있고 장시간 사용되지 않는 경우

  • 전면에 있는 액티비티가 더 많은 리소스를 필요로 하여 시스템이 백그라운드 프로세스를 종료해서 메모리를 회수해야 할 필요가 있는 경우 ( 시스템이 액티비티를 소멸시킬 수 있음 )

사용자가 Back 버튼을 누르거나 액티비티가 스스로 종료되어 소멸된 경우, Activity 인스턴스에 대한 시스템의 개념은 완전히 사라지게 됩니다. 왜냐하면 동작이 액티비티가 더 이상 필요치 않다는 것을 나타내기 때문입니다. 하지만 시스템이 정상적인 앱 동작이 아닌 시스템 제약 조건으로 인해 액티비티를 소멸한 경우, 실제 Activity 인스턴스는 사라지지만 시스템은 그것이 존재하고 있었음을 기억합니다. 예를 들어 사용자가 다시 해당 액티비티를 탐색하면, 시스템은 소멸된 액티비티의 상태를 설명하는 저장된 데이터 세트를 사용하여 액티비티의 새 인스턴스를 생성합니다.

시스템이 이전 상태를 복원하기 위해 사용하는 저장된 데이터를 "인스턴스 상태"라고 하며, 이는 Bundle 객체에 저장된 키-값 쌍의 컬렉션입니다.


기본적으로 시스템은 Bundle 인스턴스 상태를 사용하여 액티비티 레이아웃의 각 View 객체에 대한 정보를 저장합니다. 따라서 액티비티 인스턴스가 소멸되고 재생성된 경우, 레이아웃의 상태는 별도의 코드 요청 없이 이전 상태로 복원됩니다. 하지만 액티비티에서 사용자 진행 상태를 추적하는 멤버 변수처럼 액티비티에 복원하고자 하는 상태 정보가 더 많이 있는 경우도 있습니다.


※ Android 시스템이 액티비티에서 뷰의 상태를 복원하기 위해서는 android:id 특성으로 제공되는 고유 ID가 각 뷰마다 있어여 합니다.


액티비티 상태에 대한 추가 데이터를 저장하려면 onSaveInstance() 콜백 메서드를 재정의해야 합니다. 시스템은 사용자가 액티비티를 떠날 경우 이 메서드를 호출하며, 액티비티가 예기치 않게 소멸될 경우 저장되는 Bundle 객체로 전달합니다. 시스템이 나중에 액티비티 인스턴스를 재생성해야 하는 경우, 동일한 Bundle 객체를 onRestoreInstanceState() 및 onCreate() 메서드 모두에 전달합니다.



onSaveInstanceState() 메서드가 무엇인지 파악하다보니, 자연스럽게 무엇이 문제였는지 깨달았습니다. 


문제 상황의 원인

Fragment를 생성할 때, commit() 메서드를 호출하는 시점은 Activity가 상태를 저장하기 전에 이루어져야 하는데, Activity의 상태 저장 후에 이루어졌기 때문입니다.


이 문제를 해결하기 위해서 즉, Activity가 상태를 저장하고 난 후에 commit()를 하기 위해서는

commitAllowingStateLoss() 메서드를 이용해서 commit를 진행하면 됩니다.


참고 사이트 : https://developer.android.com/training/basics/activity-lifecycle/recreating?hl=ko

http://gogorchg.tistory.com/entry/Android-Can-not-perform-this-action-after-onSaveInstanceState

http://unikys.tistory.com/318

'Android > [Android] Error solution' 카테고리의 다른 글

Glide 라이브러리 사용시 유의사항  (0) 2019.01.28