如何从处理程序显示DialogFragment

Sha*_*zon 5 android android-fragments android-dialog android-dialogfragment

我有一个Handler,它在收到特定消息时显示DialogFragment.这通常有效,但如果片段已经保存,我会收到以下错误:

E/AndroidRuntime(3898):FATAL EXCEPTION:main E/AndroidRuntime(3898):java.lang.IllegalStateException:在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):at android.support.v4.app .DialogFragment.show(DialogFragment.java:123)E/AndroidRuntime(3898):at com.malauzai.app.BaseActivity $ 2.handleMessage(BaseActivity.java:72)E/AndroidRuntime(3898):at android.os.Handler.在DispatchMessage(Handler.java:99)

现在,我知道这是预期的,基于Javadoc for FragmentManager.beginTransaction:

注意:只能在活动保存其状态之前创建/提交片段事务.如果您尝试在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;
        }
      }
};
Run Code Online (Sandbox Code Playgroud)

Raf*_*l T 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
}
Run Code Online (Sandbox Code Playgroud)

  • 尽管我从未见过此问题导致此错误消息,但您绝对应该尝试拉斐尔的建议。如果您说“它从未存在”,则可能存在其他对话。将标签从“dialog”更改为“this_specific_dialog” (2认同)