반응형
- 구글 플레이 스토어 업로드 심사 중에 아래와 같은 이슈 발생으로 거절당했다.
Exception java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at androidx.fragment.app.FragmentManager.checkStateLoss (FragmentManager.java:1852)
at androidx.fragment.app.FragmentManager.enqueueAction (FragmentManager.java:1892)
at androidx.fragment.app.BackStackRecord.commitInternal (BackStackRecord.java:341)
at androidx.fragment.app.BackStackRecord.commit (BackStackRecord.java:306)
at androidx.fragment.app.DialogFragment.show (DialogFragment.java:502)
at com.day2life.timeblocks.feature.nudge.Nudge.execute (Nudge.kt:116)
at
- Fragment.show()가 onSaveInstanceState() 이후에 호출되어서 문제가 발생한 것이다.
- 프래그먼트를 show() 하면서 새로운 상태 저장에 접근하지만 이미 onSaveInstanceState() 이후에는 늦은 시점이기에 Exception이 발생한다.
- 내부적으로 show()에서는 commit() 함수를 사용하는데, 이러면 상태 저장 이후에 다시 커밋하는 행위가 문제가 될 수 있다.
- 그래서 아래와 같이 상태 저장 이후에도 또 강제로 커밋 가능하도록 함수를 구성하는 방법이 있다.
fun showAllowingStateLoss(fragmentManager: FragmentManager, tag: String? = null) {
fragmentManager.beginTransaction()
.add(this, tag)
.commitAllowingStateLoss()
}
- 하지만 그만큼 올바른 상태 복원의 로직을 보장하지 못할 수 있다. 필자는 LfieCycle을 체크하는 방식으로 대응했다.
if (baseActivity.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
//문제가 되는 프래그먼트 show() 로직
}
- Activity 혹은 Fragmenet의 라이프 사이클이 STARTED 이상인지 확인하는 것이다.
- 아예 예외 상황을 방지하는 것으로 볼 수 있다.
- 추가로 라이프 사이클 상태 값에는 다음과 같은 목록이 있다.
- INITIALIZED
- CREATED
- STARTED
- RESUMED
- DESTROYED
- isAtLeast() 함수는 현재 상태가 지정한 State 이상이면 true를 반환하는 함수이다.
반응형