android - 如何显示来自处理程序的 DialogFragment

标签 android android-fragments android-dialog android-dialogfragment

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

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): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) E/AndroidRuntime( 3898): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541) E/AndroidRuntime( 3898): at 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)

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

Note: A fragment transaction can only be created/committed prior to an activity saving its state. If you try to commit a transaction after Activity.onSaveInstanceState() (and prior to a following Activity.onStart or Activity.onResume(), you will get an error. This is because the framework takes care of saving your current fragments in the state, and if changes are made after the state is saved then they will be lost.

我的问题是我不知道如何预防它。我试过在 onPause() 上调用 Handler.removeMessages(),但它仍然发生。我已经尝试在 onSaveInstanceState() 中设置一个标志,如果设置了则不显示该 fragment ,但它仍然会发生。这似乎是一个很常见的问题,但我想不出一个可行的解决方案。基本上,我怎么知道该 fragment 已被保存?

顺便说一句,这发生在我的 BaseActivity(扩展 FragmentActivity)上,但每个 Activity 都有自己的处理程序,所以我认为这不应该成为问题。

我最后的想法是使用 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;
        }
      }
};

最佳答案

我在回答中假设您正在使用 FragmentManager 并通过带有标签(或 ID)的 FragmentTransacts 添加 fragment 。 所以基本上在你的 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
}

关于android - 如何显示来自处理程序的 DialogFragment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9105503/

相关文章:

android - Activity加载完数据后如何将数据从Activity设置到Fragment

java - 通过 XML 从 android 发送图像

android - 如何以编程方式调用 ViewPager 的下一页?

android - 如何在不知道当前 Activity 的情况下在 Android 应用程序中显示对话框

android - 在 DialogPreference 中获取正按钮

java - 这是内存泄漏吗?

java - 显示随机图像

android - getFragmentManager() 无法在自定义对话框上解析

Android fragment 转换回调

android - AlertDialog 在某些设备上破坏了布局