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变量似乎在调试器中被正确填充。

198779 次浏览

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

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

我今天也被这咬了一口,烦人的部分是getApplicationContext()是从developer.android.com逐字逐句的:(

在getApplicationContext上也一样。

android网站上的文档说可以使用,但它不起作用…了呃:p

只做:

dialog = new Dialog(this);

“这”通常是你开始对话框的Activity。

我在另一节课上也遇到过类似的问题:

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,它已经不存在了。

愚蠢愚蠢的错误,尤其是我真的不需要在第一个地方将对象保存为static……

Android文档建议使用getApplicationContext();

但它不会工作,而不是使用您的当前活动,同时实例化AlertDialog。Builder或AlertDialog或Dialog…

例:

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

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

把它改成

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

而不是

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

你也可以这样做

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

这对我很管用!!

对于嵌套对话框,这个问题是非常常见的,当它工作

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

用来代替

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

这个选择。

不要在声明dialouge时使用getApplicationContext()

总是使用this或你的activity.this

ActivityName.this代替getApplicationContext()

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

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

这需要SYSTEM_ALERT_WINDOW权限:

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

正如医生所说:

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

只有当你需要一个没有附加到活动的对话框时,你才应该使用这个解决方案。

这对我很管用

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
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);
//                          }
});
}
< p >文本:- < br > 使用此函数获取progressdialog

activity上下文
 progressdialog = new ProgressDialog(Splash.this);

progressdialog = new ProgressDialog(this);

用于获取BroadcastListener的应用程序上下文

. not for progressdialog
progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());

如上所述,你需要一个Activity作为对话框的上下文,使用“YourActivity”。或检查在这里以了解如何在安全模式下使用动态上下文

尝试将dialog窗口的类型重置为

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

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

在AsyncTask中显示“ProgressDialog”,避免内存泄漏问题的最佳和最安全的方法是使用带有loop .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);
}