背景
以下のようなアプリを作っていた時の話です。
- ある画面を開いたときにネットワーク(非同期処理中)を行う処理が行われる
- タイムアウトなどでレスポンスでエラーがあった場合に、ダイアログを表示する
この条件の時に、以下の手順を行うと以下のエラーログが表示されました。
- 通信中(レスポンスの判定処理が行われる前まで)に、ホームキーなどによりアプリをバッググラウンドに遷移させる
- タイムアウトで、エラー判定処理が走り、ダイアログを表示しようとする処理が行われる
エラーメッセージ
IllegalStateExceptionが発生しています。
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2080)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2106)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:683)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:637)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:144)
エラー発生個所
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit(); // ★★★ここで発生★★★
バッググランドになる際に表示中のFragmentのonSaveInstanceState()が呼ばれて状態が保存された後、トランザクションをコミットしようとしたことでIllegalStateExceptionが発生します。
エラー回避案1
FragmentTransaction.commit()の代わりに
FragmentTransaction.commitAllowingStateLoss()する
デメリットは以下の通り
これは文字通り「画面状態が失われてもいいからコミット」ということで、この時のコミット内容はonSaveInstanceState()で保存されなくなる。
Activityが再生成されたりすると、そのFragmentの状態が正しく復元されなくなるということだ。
これでは弊害も大きくなってしまうし、FragmentManager.popBackStack()のような処理にはそもそもAllowingStateLossなメソッドが存在しない。
参考
https://qiita.com/nein37/items/32613e9acd9558566c5e
FragmentのIllegalStateException回避 - Intelligent Technology's Technical Blog
こんにちは、間藤です。だいぶ間が空いてしまいましたが、またもやAndroidネタです。 前回は、ViewPagerを利用するうえで押さえておきたいポイントを確認してみました。今回は、Fragmentのトランザクションに関するものです。このネ...
エラー回避案2
ハンドラを使って状態の管理を行う
こちらは実は試しておらず、、、
やり方は上記のサイトを参照ください。
コメント