Android 1.6: “android.view.WindowManager$BadTokenE

2018-12-31 09:01发布

I'm trying to open a dialog window, but every time I try to open it it throws this exception:

Uncaught handler: thread main exiting due to uncaught exception
android.view.WindowManager$BadTokenException: 
     Unable to add window -- token null is not for an application
  at android.view.ViewRoot.setView(ViewRoot.java:460)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
  at android.app.Dialog.show(Dialog.java:238)
  at android.app.Activity.showDialog(Activity.java:2413)

I'm creating it by calling showDialog with the display's id. The onCreateDialog handler logs fine and I can step through it without an issue, but I've attached it since it seems like I'm missing something:

@Override
public Dialog onCreateDialog(int id)
{
    Dialog dialog;
    Context appContext = this.getApplicationContext();
    switch(id)
    {
        case RENAME_DIALOG_ID:
            Log.i("Edit", "Creating rename dialog...");
            dialog = new Dialog(appContext);
            dialog.setContentView(R.layout.rename);
            dialog.setTitle("Rename " + noteName);
            break;
        default:
            dialog = null;
            break;
    }
    return dialog;      
}

Is there something missing from this? Some questions have talked about having this problem when creating a dialog from onCreate, which happens because the activity isn't created yet, but this is coming from a call from a menu object, and the appContext variable seems like it is correctly populated in the debugger.

16条回答
公子世无双
2楼-- · 2018-12-31 09:42

Another solution is to set the window type to a system dialog:

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

This requires the SYSTEM_ALERT_WINDOW permission:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

As the docs say:

Very few applications should use this permission; these windows are intended for system-level interaction with the user.

This is a solution you should only use if you require a dialog that's not attached to an activity.

查看更多
伤终究还是伤i
3楼-- · 2018-12-31 09:45

You cannot display an application window/dialog through a Context that is not an Activity. Try passing a valid activity reference

查看更多
浪荡孟婆
4楼-- · 2018-12-31 09:45

The best and the safest way to show a 'ProgressDialog' in an AsyncTask, avoiding memory leak problem is to use a 'Handler' with Looper.main().

    private ProgressDialog tProgressDialog;

then in the 'onCreate'

    tProgressDialog = new ProgressDialog(this);
    tProgressDialog.setMessage(getString(R.string.loading));
    tProgressDialog.setIndeterminate(true);

Now you r done with the setup part. Now call 'showProgress()' and 'hideProgress()' in AsyncTask.

    private void showProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.show();
            }
        }.sendEmptyMessage(1);
    }

    private void hideProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.dismiss();
            }
        }.sendEmptyMessage(1);
    }
查看更多
倾城一夜雪
5楼-- · 2018-12-31 09:48

Try to reset dialog window's type to

WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

Don't forget to use the permission android.permission.SYSTEM_ALERT_WINDOW

查看更多
呛了眼睛熬了心
6楼-- · 2018-12-31 09:49

Instead of : Context appContext = this.getApplicationContext(); you should use a pointer to the activity you're in (probably this).

I got bitten by this today too, the annoying part is the getApplicationContext() is verbatim from developer.android.com :(

查看更多
墨雨无痕
7楼-- · 2018-12-31 09:49

Ditto on the getApplicationContext thing.

The documents on the android site says to use it, but it doesn't work...grrrrr :-P

Just do:

dialog = new Dialog(this); 

"this" is usually your Activity from which you start the dialog.

查看更多
登录 后发表回答