特定のメッセージを受信したときに DialogFragment を表示するハンドラーがあります。これは通常は機能しますが、フラグメントが既に保存されている場合は、次のエラーが発生します。
E/AndroidRuntime(3898): FATAL EXCEPTION: main E/AndroidRuntime(3898): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState E/AndroidRuntime(3898): at android.support.v4.app.FragmentManagerImpl.checkStateLoss (FragmentManager.java:1299) E/AndroidRuntime( 3898): android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) で E/AndroidRuntime( 3898): android.support.v4.app.BackStackRecord で.commitInternal(BackStackRecord.java:541) E/AndroidRuntime(3898): android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) で E/AndroidRuntime(3898): android.support.v4.app で.DialogFragment.show(DialogFragment.java:123) E/AndroidRuntime(3898): com.malauzai.app.BaseActivity$2.handleMessage(BaseActivity.java:72) E/AndroidRuntime(3898): android.os.Handler.dispatchMessage(Handler.java:99)
これで、FragmentManager.beginTransaction の Javadoc に基づいて、これが予想されることがわかりました。
注: フラグメント トランザクションは、アクティビティがその状態を保存する前にのみ作成/コミットできます。Activity.onSaveInstanceState() の後 (および次の Activity.onStart または Activity.onResume() の前) にトランザクションをコミットしようとすると、エラーが発生します。これは、フレームワークが現在のフラグメントを状態に保存するためです。状態が保存された後に変更が行われると、それらは失われます。
私の問題は、それを防ぐ方法がわからないことです。を呼び出してみましHandler.removeMessages()
たonPause()
が、まだ発生します。フラグを設定して、設定onSaveInstanceState()
されている場合はフラグメントを表示しないようにしましたが、それでも発生します。これはかなり一般的な問題のようですが、うまくいく解決策が思いつきません。基本的に、フラグメントが既に保存されていることをどのように知ることができますか?
ところで、これは BaseActivity (FragmentActivity を拡張) で発生しますが、各アクティビティには独自のハンドラーがあるため、これは問題になるとは思いません。
私の最後の考えは を使用するFragment.commitAllowingStateLoss()
ことですが、それはハックのようです。
編集: 問題を引き起こしているコードは次のとおりです。
private final Handler mTimerHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case TIMER_MESSAGE_LOGOUT_WARNING:
// throws IllegalStateException if fragment is already saved
new LogoutWarningDialog().show(getSupportFragmentManager(),
"dialog");
break;
}
}
};