본문 바로가기

나의 플랫폼/안드로이드

[Android] Can not perform this action after onSaveInstanceState

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

Fragment를 이동할때 아래와 같은 illegalStateException이 발생할 때가 있다.


Fatal Exception: java.lang.IllegalStateException

Can not perform this action after onSaveInstanceState


이건 테스트할때 잘 발생하지 않는 이슈라 그냥 넘기기 쉽지만,

참고해서 코딩하는 것도 나쁘지 않아 보인다.


이건 Exception은 Activity에서 onSaveInstanceState 함수를 호출된 상태에서 commit 함수를 호출 했을때

발생한다고 한다.


1. Activity1 onActivityCreated 에서 commit 호출

2. Activity2 로 전환

3. Activity1에서 onSaveInstanceState 호출

4. Activity2 종료

5. Activity1 onReStart 에서 commit을 호출


즉, 화면이 다시 보여진 후, Fragment 화면을 갱신하고자할 때 발생한다고 보면 된다.

http://www.kmshack.kr/2013/08/fragment-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-3-fragmentmanager-fragmenttransaction%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C/


그럼 해결은 어떻게??


commit 대신 commitAllowingStateLoss() 를 호출해라.


FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commitAllowingStateLoss();

참고하세요.


## DialogFragment 에서 show를 사용할 경우


/**
* Display the dialog, adding the fragment to the given FragmentManager. This
* is a convenience for explicitly creating a transaction, adding the
* fragment to it with the given tag, and committing it. This does
* <em>not</em> add the transaction to the back stack. When the fragment
* is dismissed, a new transaction will be executed to remove it from
* the activity.
* @param manager The FragmentManager this fragment will be added to.
* @param tag The tag for this fragment, as per
* {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}.
*/
public void show(FragmentManager manager, String tag) {
mDismissed = false;
mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
}

/** {@hide} */
public void showAllowingStateLoss(FragmentManager manager, String tag) {
mDismissed = false;
mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commitAllowingStateLoss();
}


위와 같이 commit 함수를 사용하기 때문에 Exception이 발생할 가능성이 있습니다.


따라서, DialogFragment를 아래와 같이 이용하면 좋을 듯 합니다.


getFragmentManager().beginTransaction().add(mDialogFragment, "DialogFragment Tag").commitAllowingStateLoss();

참조 : https://stackoverflow.com/a/30435080