Android – dismissDialog不会忽略该对话框

我正在使用showDialog()dismissDialog()来显示我的应用程序中的进度对话框。 从创建对话框并调用show()到使用它以便在更改方向时保存状态。

但是当我从纵向 – >横向 – >纵向更改方向时, dismissDialog()不再解除对话框。 对话框一直停留在那里,我需要按后退按钮才能消失。

有什么理由说它会这样吗?

编辑

为了解决这个问题,我尝试在onDestroy()添加一个removeDialog() ,这样就不会创建/显示对话框两次,在更改方向之前,会删除该对话框。 尝试添加日志语句,看看会发生什么

 05-21 12:35:14.064: DEBUG/MyClass(193): *************callingShowDialog 05-21 12:35:14.064: DEBUG/MyClass(193): *************onCreareDialog 05-21 12:35:15.385: DEBUG/MyClass(193): *************onSaveInstanceState 05-21 12:35:15.415: DEBUG/MyClass(193): *************onDestroy 05-21 12:35:15.585: DEBUG/MyClass(193): *************callingShowDialog 05-21 12:35:15.585: DEBUG/MyClass(193): *************onCreareDialog 05-21 12:35:15.715: DEBUG/MyClass(193): *************onCreareDialog 05-21 12:35:17.214: DEBUG/MyClass(193): *************onSaveInstanceState 05-21 12:35:17.214: DEBUG/MyClass(193): *************onDestroy 05-21 12:35:17.275: ERROR/WindowManager(193): android.view.WindowLeaked: Activity com.android.MyClass has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@43362088 that was originally added here 05-21 12:35:17.395: DEBUG/MyClass(193): *************callingShowDialog 05-21 12:35:17.395: DEBUG/MyClass(193): *************onCreareDialog 05-21 12:35:17.475: DEBUG/MyClass(193): *************onCreareDialog 

如果我们在这里看到,最初在显示活动时,会调用onCreateDialog一次并在更改方向时调用onSaveInstanceState和onDestroy。

但在那之后,onCreateDialog被调用了两次(一次是通过调用showDialog我做的,但为什么是第二次?)并且每当我改变方向时就会发生这种情况。

知道为什么会这样吗?

再次感谢

Solutions Collecting From Web of "Android – dismissDialog不会忽略该对话框"

对我来说最好的解决方案似乎是使用removeDialog(id)而不是dismissDialog(); 以这种方式减少重复使用,但更安全(不抛出任何东西)并且在更改方向时没有问题。

当在Activity的onCreate覆盖中显示一个对话框时,我遇到了这个问题。 尝试将导致对话框显示的代码移动到onPostCreate覆盖中。 这似乎对我有用。

我浪费了一天这样的问题,在调用dismissDialog时对话框没有被解雇。 它发生在我的第一次屏幕旋转之后,之后从未工作过。 我一直在使用外部AsyncTask,它明确地传递了一个引用状态。

最后解决方案非常简单…. removeDialog(int)而不是dismissDialog(int)

我花了很多时间感觉自己正在对正确的活动进行解雇并检查事情被召唤的次数等,但这是由幕后的一些jiggerypokery引起的。

我最近也遇到了这个问题。 我有一个应用程序,有许多活动都需要访问全局对象(数据库连接,数据列表等),所以我覆盖了Application类。 为此,我意识到我需要的只是对我运行中用于解除对话框的runnable中的进度对话框的最新实例的引用。 这就是我想出来的,它优雅地保留了电话重定向:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); mHandler = new Handler(); mApplication = (MyApplication)getApplication(); mFileStorage = (CheckBoxPreference)getPreferenceScreen().findPreference("fileStorage"); mProgressDialog = new ProgressDialog(this); mProgressDialog.setTitle("Location Update"); mProgressDialog.setMessage("Moving databases to new storage location."); mProgressDialog.setIndeterminate(true); mProgressDialog.setCancelable(false); mProgressDialog.setCanceledOnTouchOutside(false); mApplication.setProgressDialog(mProgressDialog); } @Override protected void onResume() { super.onResume(); mPreferences = PreferenceManager.getDefaultSharedPreferences(this); mPreferences.registerOnSharedPreferenceChangeListener(this); if (sUpdateThread != null && sUpdateThread.isAlive()) { mProgressDialog.show(); } } @Override protected void onPause() { super.onPause(); mPreferences.unregisterOnSharedPreferenceChangeListener(this); if (sUpdateThread != null && sUpdateThread.isAlive()) { mProgressDialog.hide(); mApplication.setProgressDialog(null); } } 

….随机的东西在这….

 private Runnable showProgressRunnable = new Runnable() { public void run() { mProgressDialog.show(); } }; private Runnable hideProgressRunnable = new Runnable() { public void run() { if (mApplication.getProgressDialog() != null) { mApplication.getProgressDialog().dismiss(); } } }; 

我的线程在任务启动时执行mHandler.post(showProgressRunnable),然后在任务完成时执行mHandler.post(hideProgressRunnable)。 由于对最新ProgressDialog的引用现在存储在Application类中,因此我可以可靠地将其关闭,因为我不再保留旧的对象引用。

后代链接: http : //developer.android.com/reference/android/app/Application.html

按下主页按钮并导航到app morelocal(更改设备语言)后,当我回到我的应用程序时,无法通过dismissDialog关闭新对话框(我从活动onCreate启动了对话框)。

解决方案是调用removeDialog而不是dissmissDialog()。 哈里上面推荐过这个,很多次。

我创建了一个Android错误报告:

13858


解决方案是使用OnPostCreate而不是OnCreate创建对话框。 我将该信息添加到错误报告中,并建议改进对话文档 。

请注意,每次更改方向时,都会创建一个新的Activity实例(以及通过onCreateDialog创建的Dialog实例)。 您可以通过在任一构造函数中添加日志语句来validation这一点。

虽然很难说没有看一下你的代码,但我猜你是在一个旧的Activity实例上调用dismissDialog

考虑下面的Activity ,当单击一个按钮时,它只显示一个空的Dialog ,并在10秒后启动TimerTask以解除它:

 public class Test extends Activity { private Dialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test); Button btn = (Button) findViewById(R.id.testButton); btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { new Timer().schedule(new TimerTask() { @Override public void run() { dialog.dismiss(); } }, 10000); Test.this.showDialog(1); } }); } @Override protected Dialog onCreateDialog(int id) { if(id == 1) { if(dialog == null) { dialog = new Dialog(this); } return dialog; } return super.onCreateDialog(id); } } 

此代码存在类似于您所描述的问题:如果 – 在10秒内 – 方向已更改,则Dialog永远不会被解除。 为什么? 因为在run TimerTask ,已经创建了一组完整的TestDialog实例(在方向更改期间),并且TimerTaskdialog实例variables引用了一个与当前活动的实例不同的Test实例。屏幕。

显然有几种方法可以解决这个问题(主要取决于你的应用程序),修复上面代码的一种快速(脏?)方法就是简单地使dialog字段为static

 private static Dialog dialog; 

在搜索各种论坛后,我刚刚做了以下事情:

我从我的处理程序调用了handleDialog(MyDialogID)和dismissDialog(MyDialogId)中的handleMessage(myMessage)方法。

在此之前,我在我的onCreate() – Method中调用了showDialog,并尝试在handle-Message中关闭对话框。 为什么这解决了这个问题,我不能说。

我正在试验同样的问题。 我在onCreateDialog()回调中创建了一个AlertDialog和一个ProgressDialog ,并从onCreate()显示它们。 直接在onCreate创建这些对话框(不使用onCreateDialog() )并在onPause()解雇它们对我onPause() ! 基于https://stackoverflow.com/a/5693467/955619

  private AlertDialog alert11 = null; public void gpsDialog(){ if (alert11 == null || !alert11.isShowing()) { AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this); builder1.setMessage("GPS not On"); builder1.setCancelable(true); builder1.setPositiveButton("Enable GPS", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); MainActivity.this.startActivity(intent); dialog.dismiss(); } }); builder1.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }); alert11 = builder1.create(); alert11.show(); } }