Android 1.6:“android.view.WindowManager $ BadTokenException:无法添加窗口 – 标记null不适用于应用程序”

我试图打开一个对话框窗口,但每次我试图打开它会引发这个异常:

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) 

我用显示器的ID调用showDialog创建它。 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; } 

有没有从这个缺少的东西? 从onCreate创建一个对话框时,有一些问题已经讨论了这个问题,这是因为活动还没有创建,但这是来自菜单对象的调用,而appContext变量好像正确地填充在调试器。

即这一行: Context appContext = this.getApplicationContext(); 必须去,而是使用一个指向你所在的活动的指针(可能是这个)。

今天我也被这个咬了,讨厌的部分是getApplicationContext()是逐字从developer.android.com 🙁

您不能通过不是活动的上下文显示应用程序窗口/对话框。 尝试传递有效的活动参考

同上getApplicationContext的东西。

在Android网站上的文件说要使用它,但它不工作… grrrrr 😛

做就是了:

 dialog = new Dialog(this); 

“this”通常是您从其开始对话的活动。

Android文档建议使用getApplicationContext();

但它不会工作,而不是使用您当前的活动,而实例化AlertDialog.Builder或AlertDialog或对话框…

例如:

 AlertDialog.Builder builder = new AlertDialog.Builder(this); 

要么

 AlertDialog.Builder builder = new AlertDialog.Builder((Your Activity).this); 

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

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

 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(); } } 

大部分时间都工作得很好,但是有时也会碰到同样的错误。 然后我意识到,在MyActivity我有…

 public class MyActivity extends Activity { public static Something something; public void someMethod() { if (something==null) { something=new Something(this); } } } 

因为我把对象当作static对象,代码的第二次运行仍然保持对象的原始版本,因此仍然指的是原来的Activity ,这个Activity不存在。

愚蠢的错误,特别是因为我真的不需要把对象固定在首位…

把它改成

 AlertDialog.Builder alert_Categoryitem = new AlertDialog.Builder(YourActivity.this); 

代替

 AlertDialog.Builder alert_Categoryitem = new AlertDialog.Builder(getApplicationContext()); 

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

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

这需要SYSTEM_ALERT_WINDOW权限:

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

正如文件所说:

很少的应用程序应该使用此权限; 这些窗口用于与用户进行系统级的交互。

如果您需要一个没有附加到活动的对话框,则应该只使用这个解决方案。

不要使用getApplicationContext()声明dialouge

总是使用this或你的activity.this

这为我工作 –

 new AlertDialog.Builder(MainActivity.this) .setMessage(Html.fromHtml("<b><i><u>Spread Knowledge Unto The Last</u></i></b>")) .setCancelable(false) .setPositiveButton("Dismiss", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { } }).show(); 

使用

 ActivityName.this 

对于嵌套对话框这个问题是非常普遍的,它工作的时候

 AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this); 

被用来代替

 mDialogBuilder = new AlertDialog.Builder(getApplicationContext); 

这个选择。

你也可以做到这一点

 public class Example extends Activity { final Context context = this; final Dialog dialog = new Dialog(context); } 

这对我有效!

正如所说的,你需要一个Activity作为对话框的上下文,使用“YourActivity.this”作为静态上下文,或者在这里查看如何在安全模式下使用动态的

尝试重置dialog窗口的类型

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

不要忘记使用权限android.permission.SYSTEM_ALERT_WINDOW

 public class Splash extends Activity { Location location; LocationManager locationManager; LocationListener locationlistener; ImageView image_view; ublic static ProgressDialog progressdialog; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.splash); progressdialog = new ProgressDialog(Splash.this); image_view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub locationManager.requestLocationUpdates("gps", 100000, 1, locationlistener); Toast.makeText(getApplicationContext(), "Getting Location plz wait...", Toast.LENGTH_SHORT).show(); progressdialog.setMessage("getting Location"); progressdialog.show(); Intent intent = new Intent(Splash.this,Show_LatLng.class); // } }); } 

在这打字:-
使用它获取progressdialog activity上下文

  progressdialog = new ProgressDialog(Splash.this); 

或者progressdialog = new ProgressDialog(this);

使用它来获取BroadcastListener应用程序上下文而不是progressdialog

 progressdialog = new ProgressDialog(getApplicationContext()); progressdialog = new ProgressDialog(getBaseContext()); 

在AsyncTask中显示“ProgressDialog”,避免内存泄漏问题的最好也是最安全的方法是在Looper.main()中使用“Handler”。

  private ProgressDialog tProgressDialog; 

那么在“onCreate”

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

现在你完成了设置部分。 现在在AsyncTask中调用“showProgress()”和“hideProgress()”。

  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); }