屏幕方向更改后关闭对话框

fhu*_*cho 14 android

1)我启动后台任务(通过AsyncTask)

new FindJourneyTask().execute(); // FindJourneyTask extends AsyncTask
Run Code Online (Sandbox Code Playgroud)

2)仍然在主线程中(在新线程启动之前)我创建一个带有showDialog的对话框(dialogId)

// this method is in FindJourneyTask
protected void onPreExecute() {
    showDialog(DIALOG_FINDING_JOURNEY);
}
Run Code Online (Sandbox Code Playgroud)

3)屏幕方向更改并重新创建活动

4)我现在如何从FindJourneyTask中删除对话框?调用dismissDialog(dialogId)什么都不做.

// this method is in FindJourneyTask
protected void onPostExecute(FindJourneyResult result) {
    dismissDialog(DIALOG_FINDING_JOURNEY); // does nothing
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*Lew 22

这是一个常见问题,并没有真正好的解决方案.问题是,在屏幕方向更改时,整个活动将被销毁并重新创建.同时,您在之前使用的Dialog在新的Activity中重新创建,但旧的后台任务在尝试关闭对话框时仍然引用旧的Activity.结果是它解雇了一个很久以前被破坏的对话框,而不是忽略了新方向创建的对话框.

有三种基本解决方案:

  1. 覆盖默认的方向处理代码,以便在旋转时不会销毁您的活动.这可能是最不令人满意的答案,因为它阻止了许多在方向更改时自动运行的代码.

  2. 创建一个引用Activity本身的Activity的静态成员变量,以便调用STATIC_ACTIVITY_VARIABLE.dismissDialog().

  3. 编写一个解决方案,其中后台任务跟踪当前活动并根据需要自行更新.

这三个解决方案在这里详细讨论:http://groups.google.com/group/android-developers/browse_thread/thread/bf046b95cf38832d/


Mal*_*olm 10

现在有一个更好的解决这个问题的方法,它涉及使用片段.

如果使用DialogFragment创建对话框,则此片段将负责维护对话框的生命周期.显示对话框时,为片段提供标记(DialogFragment.show()).当您需要访问对话框时,只需使用FragmentManager.findFragmentByTag查找必要的DialogFragment,而不是引用对话框本身.

这样,如果设备更改方向,您将获得一个新片段而不是旧片段,一切都会起作用.

这里有一些基于@peresisUser答案的代码:

public void onSaveInstanceState(Bundle outState) {
   AppCompatActivity activity = (AppCompatActivity) context;
   FragmentManager fragmentManager = activity.getSupportFragmentManager();
   DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag("your_dialog_tag");
   if(dialogFragment!=null) {
      Dialog dialog = dialogFragment.getDialog();
      if(dialog!=null && dialog.isShowing()) {
         dialogFragment.dismiss();
      }
   }
}
Run Code Online (Sandbox Code Playgroud)