5

我有一个处理程序,它在收到特定消息时显示一个 DialogFragment。这通常有效,但如果片段已被保存,我会收到以下错误:

E/AndroidRuntime(3898):致命异常:主要 E/AndroidRuntime(3898):java.lang.IllegalStateException:onSaveInstanceState 后无法执行此操作 E/AndroidRuntime(3898):在 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(),但这似乎是一个 hack。

编辑: 这是导致我出现问题的代码:

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;
        }
      }
};
4

1 回答 1

1

我在我的回答中假设您正在使用 FragmentManager 并通过带有标签(或 ID)的 FragmentTransacts 添加片段。所以基本上在你里面BaseActivity你可以做这样的事情

FragmentManager manager = getFragmentSupportedManager();
Fragment fragmentIWannaKnowIfexists = manager.findFragmentByTag("Tag I used to create this Fragment inside FragmentTrasnsaction")
// or manager.findFragmentById(ID_FROM_LAYOUT)
if(fragmentIWannaKnowIfexists != null){
    //we have this Fragment already
} else {
    // this Fragment was not added already
}
于 2012-02-02T01:02:07.113 回答