본문 바로가기

Android/Trouble Shoot

ViewModel 의 illegalStateException: Can not perform this action after onSaveInstanceState

앱 <산책갈까?> 리팩토링 중 만나게 된 예외입니다.

위치 서비스 권한을 획득하기 위해 Callback 을 두고 Intent 로 위치 서비스 설정 창으로 이동합니다.

위치 서비스를 사용하도록 설정한 뒤 돌아와 즉시 ViewModel 을 참조하니 발생한 에러입니다.

 

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

 

onSaveInstanceState() 이후에 해당 액션을 진행할 수 없다고 나옵니다.

 

이는 안드로이드 액티비티의 생명주기와 관련한 예외입니다.

onSaveInstanceState() 에 액티비티에서 참조가 남아있는 객체들을 저장합니다.

onSaveInstanceState() 는 onStop() 과 onDestory() 사이에 호출되며, 설정 변경이나 앱 종료가 아니기 때문에 액티비티는 파괴되지 않으므로 onDestory() 는 호출되지 않습니다.

 

액티비티는 onStop() 과 onSaveInstanceState() 까지 호출된 상태이기 때문에, 설정을 마치고 백버튼을 눌러 다시 액티비티로 돌아오게 되면 onRestart() 가 호출되고 이후 바로 onStart() 가 호출됩니다.

onSaveInstanceState() 에서 저장된 viewModel 의 인스턴스는 onStart() 와 onResume() 의 사이에 호출되는

onRestoreInstanceState() 에서 다시 참조할 수 있게 되는데, onStart() 와 onRestoreInstanceState() 사이에 Callback 이 들어오니 참조할 ViewModel 이 없어 해당 예외를 던지는 것입니다.

 

// 생명주기 / 호출된 시간
I/System.out: onStop 1667923796409
I/System.out: onSaveInstanceState 1667923796409
I/System.out: onRestart 1667923797714
I/System.out: onStart 1667923797715
// onResume 과 onRestoreStateInstance 에 대해서도 메시지를 프린트하도록 구현하였으나, 호출되지 않음.

 

직접 순서도를 그려보면 쉽게 파악할 수 있습니다.

 

3번에서 저장한 객체를 6번에서 돌려받는데 5번에서 참조하려니 에러가 날 수 밖에 없습니다.

 


 

사실 예외 메시지가 NPE 였으면 더 직관적일 수 있었을 것입니다.

LifecycleScope 코드 블록에서 delay() 메서드로 시간차를 두어 해결했습니다.