Android 当应用程序恢复时,被驳回的对话框片段再次出现

Android 当应用程序恢复时,被驳回的对话框片段再次出现,android,android-fragments,android-fragmentactivity,android-dialogfragment,Android,Android Fragments,Android Fragmentactivity,Android Dialogfragment,嗨,我正在开发一个使用地图的应用程序 我正在使用片段活动和一个名为Fragment-a的片段 在Fragment-A中有一个按钮,单击该按钮会弹出一个对话框片段,显示一个带有以前从服务器接收到的某个位置的地图 让我们假设这个对话片段是DialogFragment-B FragmentManager fm = getFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); android.app.Fragm

嗨,我正在开发一个使用地图的应用程序

我正在使用片段活动和一个名为Fragment-a的片段

在Fragment-A中有一个按钮,单击该按钮会弹出一个对话框片段,显示一个带有以前从服务器接收到的某个位置的地图

让我们假设这个对话片段是DialogFragment-B

FragmentManager fm = getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    android.app.Fragment prev = fm.findFragmentByTag(MY_MAP);
    if (prev != null) {
        ft.remove(prev);
    }
    MyMapFragmentDialog newFragment = MyMapFragmentDialog
            .newInstance(eachPost);
    newFragment.show(ft, MY_MAP);
它有一个按钮可以关闭,一个按钮可以导航到谷歌地图应用程序获取方向

如果用户导航到DialogFragment-B并返回到Fragment-A,则通过单击“关闭”按钮,一切正常

但是,如果用户单击后退按钮,现有的对话框片段将正常关闭,应用程序将正常运行

但是,如果用户随后按下home按钮或接到电话,并且即使DialogFragment-B先前已被取消,仍会调用onResume,则它会重新出现,按close会导致应用程序崩溃,出现空指针异常

这是我打开对话框fragment-B的代码

FragmentManager fm = getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    android.app.Fragment prev = fm.findFragmentByTag(MY_MAP);
    if (prev != null) {
        ft.remove(prev);
    }
    MyMapFragmentDialog newFragment = MyMapFragmentDialog
            .newInstance(eachPost);
    newFragment.show(ft, MY_MAP);
在DialogFragment-B中,单击close按钮,我调用MyMapFragmentDialog.this.disease()

如果有人遇到并克服了这个问题,请指导我解决。

更新:卡琳娜的答案是一个更优雅、更简单的解决方案——正如我后来发现的那样

我在我的一个应用程序中遇到了同样的问题,但在任何地方都找不到答案,我浏览了DialogFragment类的源代码,该类可从以下网址获得:

在那里,我在onDismiss(DialogInterface dialog)方法的源代码中找到了一条注释中所写的可能原因:

我从中了解到,撤销不会保存到实例状态,当活动恢复时,它会立即再次显示它,作为实例状态恢复的一部分-假设片段从未被撤销。作为一个异步事件,没有一种安全的方法可以在不冒失败风险的情况下提交解雇

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
异常和随后的崩溃,这可能就是类的作者选择这种方式的原因

对我有效的解决方案是通过以下方式单独监控DialogFragment的状态:

  • 将其存储在类变量中(此处称为“对话框”)
  • 重写onDismiss(DialogInterface dialog)方法,以及
  • 将布尔DialogDisposed标志设置为true
-

  • 注意:如果DialogFragment是一个单独的类,那么需要从onDismiss调用活动中的一个方法来实现这一点,可能需要设置一个接口

  • 然后必须在activity onResume()中选中此标志,并强制关闭(在检查对话框是否为空后):

-


我遇到了同样的问题,通过确保在我的
DialogFragment
子类的
onDismiss
方法中调用
super.onDismiss(dialog)
解决了这个问题。

我认为您忽略了提交事务:
ft.remove(prev.commit()
或添加另一行,如
ft.commit()在if循环中尝试
MyMapFragmentDialog
prev
变为空,您将片段添加到itI中时遇到了相同的问题,这修复了我的问题。如果我正在工作,请纠正我,我将尝试提供一个解释。据我所知,当您在父活动中使用dismise()方法时(您首先创建了对话框片段并使用了dialogFragment.show()),dismise()方法是有效的。onDismiss(dialog)也执行相同的操作,但在dialog片段类中“超级”只是从其父级(创建它的活动)执行。
@Override
public void onDismiss(DialogInterface dialog) {
   // dialogDismissed is a Class level variable in the containing Activity,
   // must be set to false each time the DialogFragment is shown
   dialogDismissed = true;
}
@Override
public void onResume() {
super.onResume();
//...
if (dialogDismissed && dialog != null) {
        dialog.dismiss();
    }    
}