Android 1.6:"android.view.WindowManager $ BadTokenException:无法添加窗口 - 令牌null不适用于应用程序"

Dan*_*ego 301 android runtimeexception android-dialog android-windowmanager

我正在尝试打开一个对话框窗口,但每次我尝试打开它都会抛出此异常:

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

我是通过showDialog显示器的id 调用来创建的.该onCreateDialog处理器记录良好,我可以通过它没有问题的一步,但因为它看起来像我想的东西我已经把它贴吧:

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

这有什么不足之处吗?有些问题在创建对话框时已经讨论过这个问题onCreate,因为活动尚未创建,但这是来自菜单对象的调用,而appContext变量似乎在调试器中正确填充.

Tor*_*orp 608

而不是: Context appContext = this.getApplicationContext(); 你应该使用指向你所在活动的指针(可能this).

我今天也被这个咬了,令人讨厌的部分是getApplicationContext()来自developer.android.com的逐字:(

  • 以防这有助于任何人 - 在对话框中使用myActivity.this作为上下文. (63认同)
  • 这个问题和答案在2天内变成3岁.我仍然获得声誉,所以我猜谷歌仍然没有修复他们的文档...... (13认同)
  • 这是2016年4月,仍然是这个异常使应用程序在对话启动时崩溃. (6认同)
  • 它也被报告为一个错误(虽然不是在用户发布问题时):http://code.google.com/p/android/issues/detail?id = 11199 (2认同)
  • 这已在(http://developer.android.com/guide/topics/ui/dialogs.html)中修复 (2认同)
  • 2016年8月在这里,在尝试[此](http://stackoverflow.com/questions/17944061/how-to-use-number-picker-with-dialog#comment65243784_17944168)回答后仍然得到了它. (2认同)

Sam*_*muh 78

您无法通过非活动的上下文显示应用程序窗口/对话框.尝试传递有效的活动参考

  • 得到它了.直接在其中传递您的活动名称.没有`.this`. (3认同)

ken*_*yee 45

同样关于getApplicationContext的事情.

android网站上的文件说要使用它,但它不起作用...... grrrrr :-P

做就是了:

dialog = new Dialog(this); 
Run Code Online (Sandbox Code Playgroud)

"this"通常是您启动对话框的Activity.


Pra*_*eep 43

Android文档建议使用getApplicationContext();

但在实例化AlertDialog.Builder或AlertDialog或Dialog时,它将无法使用您当前的活动...

例如:

AlertDialog.Builder builder = new  AlertDialog.Builder(this);
Run Code Online (Sandbox Code Playgroud)

要么

AlertDialog.Builder builder = new  AlertDialog.Builder((Your Activity).this);
Run Code Online (Sandbox Code Playgroud)


mah*_*que 17

而不是getApplicationContext(),只是使用ActivityName.this


小智 13

我有一个类似的问题,我有另一个类这样的东西:

public class Something {
  MyActivity myActivity;

  public Something(MyActivity myActivity) {
    this.myActivity=myActivity;
  }

  public void someMethod() {
   .
   .
   AlertDialog.Builder builder = new AlertDialog.Builder(myActivity);
   .
   AlertDialog alert = builder.create();
   alert.show();
  }
}
Run Code Online (Sandbox Code Playgroud)

大部分时间工作正常,但有时它会因同样的错误而崩溃.然后我意识到MyActivity我...

public class MyActivity extends Activity {
  public static Something something;

  public void someMethod() {
    if (something==null) {
      something=new Something(this);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

因为我把对象保持为static,所以代码的第二次运行仍然保持对象的原始版本,因此仍然指的是Activity不再存在的原始版本.

愚蠢的愚蠢错误,特别是因为我真的不需要像static第一个那样握住物体......


Sat*_*esh 12

只需将其更改为

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(YourActivity.this);
Run Code Online (Sandbox Code Playgroud)

代替

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(getApplicationContext());
Run Code Online (Sandbox Code Playgroud)


Anu*_*oob 9

另一种解决方案是将窗口类型设置为系统对话框:

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Run Code Online (Sandbox Code Playgroud)

这需要SYSTEM_ALERT_WINDOW许可:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Run Code Online (Sandbox Code Playgroud)

正如文档所说:

很少有申请人应该使用此权限; 这些窗口用于与用户进行系统级交互.

这是一个解决方案,只有在需要一个未附加到活动的对话框时才能使用.