Android – dismissDialog不closures对话框

我使用showDialog()dismissDialog()在我的应用程序中显示进度对话框。 从创build对话框和调用show()到它的使用,以改变方向时保存状态。

但是,当我从纵向 – >横向 – >纵向更改方向时, dismissDialog()不再取消对话框。 该对话框始终保持在那里,我需要按下后退button使其消失。

为什么会这样呢?

编辑

为了克服这个问题,我尝试在onDestroy()添加一个removeDialog() ,这样对话框不会被创build/显示两次,在方向改变之前,对话框将被删除。 试着添加日志语句,看看会发生什么

 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 

如果我们在这里看到,最初当activity被显示时,onCreateDialog被调用一次,当改变方向时,onSaveInstanceState和onDestroy被调用。

但之后,onCreateDialog被调用两次(一次调用showDialog,我做了,但为什么第二次?),每当我改变方向,因此发生这种情况。

任何想法为什么发生?

再次感谢

Solutions Collecting From Web of "Android – dismissDialog不closures对话框"

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

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

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

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

我花了一些时间,觉得自己永远向自己certificate自己是在对正确的行为进行驳回,并检查事情的次数等等,但这是由幕后的一些琐事所引起的。

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

 @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类中,所以我可以可靠地将其closures,因为我不再保留旧的对象引用。

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

按Homebutton并导航到应用程序morelocal(更改设备语言)后,当我回到我的应用程序,新的对话框不能通过dismissDialogclosures(我启动对话框活动onCreate)。

解决的办法是调用removeDialog而不是dissmissDialog()。 这已经被上面的哈里推荐,许多thx。

我已经创build了一个Android错误报告:

13858


解决scheme是使用OnPostCreate而不是OnCreate来创build对话框。 我将这些信息添加到错误报告中,并build议改进对话框文档 。

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

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

考虑下面的Activity ,当点击一个button时,它只显示一个空的Dialog ,并在10秒后启动一个TimerTask来closures它:

 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 ,已经创build了一组完整的TestDialog实例(在方向更改期间),并且TimerTaskdialog实例variables引用了与当前活动的Test实例不同的Test实例屏幕。

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

 private static Dialog dialog; 

通过各种论坛search,我只是做了以下几点:

我从我的Handler中调用showDialog(MyDialogID)AND dismissDialog(MyDialogId)handleMessage(myMessage)方法。

在此之前,我在我的onCreate() – 方法中调用了showDialog,并尝试closures句柄消息中的对话框。 为什么这解决了这个问题,我不能告诉。

我正在试验同样的问题。 我在onCreateDialog()callback中创build了一个AlertDialog和一个ProgressDialog ,并从onCreate()显示出来。 直接在onCreate (不使用onCreateDialog() )创build这些对话框,并在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(); } }