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)
Я создаю это, позвонив 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()
Verbatim от Developer.Android.com :(
Другие советы
Вы не можете отобразить окно / диалоговое окно приложения через контекст, который не является активностью. Попробуйте пройти допустимую ссылку на активность
То же самое на GetaplicationContext вещь.
Документы на сайте Android говорят, что это использовать, но это не работает ... grrrrr :-p
Просто делать:
dialog = new Dialog(this);
"это" Обычно ваша активность, из которой вы запускаете диалог.
Android-документы предлагают использовать GetapplicationContext ();
Но вместо этого не будет работать, что использует вашу текущую активность во время создания AlertDialog.Builder или AlertDialog или Dialog ...
Бывший:
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);
}
Это работало для меня !!
Как сказано, вам нужна деятельность в качестве контекста для диалогового окна, используйте «Youractive.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);
// }
});
}
Текст здесь: -
Используйте это для получения activity
контекст для progressdialog
progressdialog = new ProgressDialog(Splash.this);
или progressdialog = new ProgressDialog(this);
Используйте это для получения контекста приложения для BroadcastListener
не для progressdialog
.
progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
Лучший и самый безопасный способ показать «ProgressDialog» в асинктике, избегая проблемы утечки памяти - использовать «обработчик» с Looper.main ().
private ProgressDialog tProgressDialog;
Тогда в «Oncreate»
tProgressDialog = new ProgressDialog(this);
tProgressDialog.setMessage(getString(R.string.loading));
tProgressDialog.setIndeterminate(true);
Теперь вы сделали с деталью настройки. Теперь позвоните «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);
}