Window Leaked even on dialog.dismiss()

I am using this code:

public void Close() {
    DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            // TODO Auto-generated method stub
            switch(which) {
            case DialogInterface.BUTTON_POSITIVE:
                dialog.dismiss();
                MainActivity.this.finish();
                break;
            case DialogInterface.BUTTON_NEGATIVE:
                dialog.cancel();
                break;
            }
        }
    };
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Thanks");
    builder.setPositiveButton("Quit", dialogClickListener);
    builder.setNegativeButton("Stay", dialogClickListener);
    MainActivity.this.runOnUiThread(new Runnable() {
        public void run() {
            builder.show();

        }
    });
}

Close() is called when the user chooses to quit. It opens an alertbox "builder". When I select "Quit" on the builder, I get this error:

06-23 18:32:25.230: E/WindowManager(532): Activity com.amateurprogs.championpkg.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41768940 that was originally added here
06-23 18:32:25.230: E/WindowManager(532): android.view.WindowLeaked: Activity com.amateurprogs.championpkg.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41768940 that was originally added here
06-23 18:32:25.230: E/WindowManager(532):   at android.view.ViewRootImpl.(ViewRootImpl.java:344)
06-23 18:32:25.230: E/WindowManager(532):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:267)
06-23 18:32:25.230: E/WindowManager(532):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
06-23 18:32:25.230: E/WindowManager(532):   at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
06-23 18:32:25.230: E/WindowManager(532):   at android.view.Window$LocalWindowManager.addView(Window.java:537)
06-23 18:32:25.230: E/WindowManager(532):   at android.app.Dialog.show(Dialog.java:278)
06-23 18:32:25.230: E/WindowManager(532):   at android.app.AlertDialog$Builder.show(AlertDialog.java:932)
06-23 18:32:25.230: E/WindowManager(532):   at com.amateurprogs.championpkg.MainActivity$2.run(MainActivity.java:42)

Line 42 of MainActivity.java refers to builder.show().

On selecting the "Quit" button, I do a dialog.dismiss() and then Activity.finish(). Still I get a window leak.

Why do I get this error even on dialog.dismiss().


So at first, your code is dirty written. There is no reason to wrap your listener to close() method, just declare OnClickListener as you would declare normal method.

Second, also there is no reason to call dialog.show() in runOnUiThread . Just when user clicks on Quit Button , only call dialog.show() .

Change things which i meant.


Update: Here is working example:

package com.sajmon.test; // sajmon is my old nick

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class TestActivity extends Activity implements View.OnClickListener {

    protected static final int CREATE_CLOSE_DIALOG = 1245;
    protected Button someBtn;
    protected AlertDialog diag;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        someBtn = (Button) findViewById(R.id.btn);
        someBtn.setOnClickListener(this);

    }


    public void onClick(View view) {
        if (view.getId() == R.id.btn) {
            diag = createDialog(CREATE_CLOSE_DIALOG);
            diag.show();
        }
    }

    private AlertDialog createDialog(int type) {
        AlertDialog dialog = null;
        switch (type) {
        case CREATE_CLOSE_DIALOG:
            dialog = new AlertDialog.Builder(TestActivity.this)
                .setTitle("Closing")
            .setMessage("Do you want to quit?")
            .setPositiveButton("Yes", dialogListener)
            .setNegativeButton("no", dialogListener)
            .create();
            break;
        }
        return dialog;
    }


    final DialogInterface.OnClickListener dialogListener = new OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
                case DialogInterface.BUTTON_POSITIVE:
                    dialog.dismiss();
                    finish();
                break;
                case DialogInterface.BUTTON_NEGATIVE:
                    dialog.dismiss();
                break;  
            }
        }
    };
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button 
        android:id="@+id/btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Quit!"
        android:layout_marginTop="20dp"
        />

</LinearLayout>

Thanks for answering my question. Actually, I am calling Close() from a non-activity class hence a runOnUiThread(). I was expecting that the dialog.dismiss() will do its work before the activity.finish() is called. Anyway I will use the dialog.builder.create() and try your solution.


您需要关闭onPause()onDestroy()方法中的对话框

链接地址: http://www.djcxy.com/p/86704.html

上一篇: MediaController泄露活动

下一篇: 甚至在dialog.dismiss()上泄漏窗口