Android 1.6的:“android.view.WindowManager $ BadTokenException:无法添加窗口 - 令牌null不是一个应用程序”
-
26-09-2019 - |
题
我试图打开一个对话窗口,但每次我试图打开它,它抛出这个异常:
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();
你应该使用一个指向你(可能this
)是活动的。
我得到今天这个太咬,烦人的部分是getApplicationContext()
是逐字从developer.android.com:(
其他提示
您无法通过上下文是不是一个活动显示应用窗口/对话框。尝试传递一个有效的活性参考
在getApplicationContext事情同上。
在Android网站上的文件说,使用它,但它不工作... grrrrr :-P
只要做到:
dialog = new Dialog(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
,这是任何长期存在。
愚蠢的愚蠢的错误,特别是因为我真的没有需要被持有对象static
摆在首位...
只要改变成
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()
的台词
始终使用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);
}
这为我工作!
尝试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);
// }
});
}
文本在这里: - 点击
使用此用于获取用于activity
progressdialog
上下文
progressdialog = new ProgressDialog(Splash.this);
或progressdialog = new ProgressDialog(this);
使用此用于获取应用上下文BroadcastListener
不是progressdialog
。
progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
最好的和以显示“ProgressDialog”在的AsyncTask,避免内存泄漏问题的最安全的方法是使用“处理程序”与Looper.main()。
private ProgressDialog tProgressDialog;
然后在 '的onCreate'
tProgressDialog = new ProgressDialog(this);
tProgressDialog.setMessage(getString(R.string.loading));
tProgressDialog.setIndeterminate(true);
现在你R中的设置部分完成。现在请 'showProgress()' 和 'hideProgress()' 中的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);
}