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.结果是它解雇了一个很久以前被破坏的对话框,而不是忽略了新方向创建的对话框.
有三种基本解决方案:
覆盖默认的方向处理代码,以便在旋转时不会销毁您的活动.这可能是最不令人满意的答案,因为它阻止了许多在方向更改时自动运行的代码.
创建一个引用Activity本身的Activity的静态成员变量,以便调用STATIC_ACTIVITY_VARIABLE.dismissDialog().
编写一个解决方案,其中后台任务跟踪当前活动并根据需要自行更新.
这三个解决方案在这里详细讨论: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)