Android - dismissDialog不会忽略该对话框

los*_*sit 22 android

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

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

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

编辑

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

知道为什么会这样吗?

再次感谢

Har*_*rri 8

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


小智 6

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


Uni*_*iqe 5

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

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

我曾经感受到永远向自己证明我正在对正确的活动进行解雇并检查事情被召唤的次数等,但这是由幕后的一些jiggerypokery引起的.


Jos*_*ger 0

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

虽然在不看代码的dismissDialog情况下很难说,但我猜你正在调用Activity.

考虑以下情况,当单击按钮时Activity仅显示一个空,并在 10 秒后启动 a 将其关闭:DialogTimerTask

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码有一个与您所描述的问题类似的问题:如果 - 在 10 秒内 - 方向发生变化,则Dialog永远不会被忽略。为什么?因为此时TimerTaskis已经创建了run一组完全不同的Test和实例(在方向更改期间),并且的实例变量引用的实例与屏幕上当前活动的实例不同。DialogTimerTaskdialogTest

显然,有多种方法可以处理这个问题(主要取决于您的应用程序),修复上述代码的一种快速(肮脏?)方法是简单地创建该dialog字段static

private static Dialog dialog;
Run Code Online (Sandbox Code Playgroud)