ProgressDialog和AlertDialog导致泄漏的窗口问题

10

我有一个Activity,如果第一次启动就会显示欢迎信息:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    showWelcomeMessageIfNecessary();
}

private void showWelcomeMessageIfNecessary() {
    final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    final Editor edit = prefs.edit();

    if (!prefs.getBoolean("welcomemessage", false)) {
        edit.putBoolean("welcomemessage", true);
        edit.commit();

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(R.string.messages_welcome_content).setCancelable(false).setPositiveButton(R.string.errors_ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                // Do nothing
            }
        }).setTitle(R.string.messages_welcome_title);
        AlertDialog alert = builder.create();
        alert.show();
    }
}

这一切都很完美,但是当我启动应用并立即旋转屏幕时,就会出现众所周知的泄漏窗口异常。

我该如何避免这种情况?是否有更好的方法来显示对话框?当我在片段中使用AsyncTaskProgressDialog时,也会发生这种情况。


也许是 new AlertDialog.Builder(this.getParent());,不确定。 - Samir Mangroliya
1个回答

18

您需要在Activity的 onStop onDestroy 方法中取消对话框。例如:

private AlertDialog diag = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    diag = showWelcomeMessageIfNecessary();

    if(diag != null)
        diag.show();
}

private AlertDialog showWelcomeMessageIfNecessary() {
    final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    final Editor edit = prefs.edit();
    AlertDialog alert = null;

    if (!prefs.getBoolean("welcomemessage", false)) {
        edit.putBoolean("welcomemessage", true);
        edit.commit();

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(R.string.messages_welcome_content).setCancelable(false).setPositiveButton(R.string.errors_ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                // Do nothing
            }
        }).setTitle(R.string.messages_welcome_title);
        alert = builder.create();
    }

    return alert;
}


@Override
protected void onStop() {
    super.onStop();

    if(diag != null)
        diag.dismiss();
}

好的,这个可以工作。我现在明白了。如果你不在 onStop() 中解除对话框,那么对话框仍然会显示,并附加到旧的 Activity 上。有点混淆,因为异常发生在 onShow() 行,让我认为是在开始显示对话框时泄漏了窗口。 - nhaarman
是的,当一个活动上的对话框被设置为可见,但是该活动本身被销毁时,就会导致窗口泄漏错误。 - waqaslam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接