Android 1.6: „android.view.WindowManager $ BadTokenException: Nicht imstande, Fenster hinzuzufügen - Token null ist nicht für eine Anwendung“
-
26-09-2019 - |
Frage
Ich versuche, ein Dialogfenster zu öffnen, aber jedes Mal, wenn ich versuche, es zu öffnen, führt es diese Ausnahme:
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)
Ich schaffe es durch showDialog
mit der Anzeige der ID aufrufen. Der onCreateDialog
Handler protokolliert fein und ich kann ohne ein Problem durch Schritt, aber ich habe es angebracht, da es scheint, wie ich etwas fehlt:
@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;
}
Gibt es etwas von diesem fehlt? Einige Fragen haben darüber gesprochen, dieses Problem zu haben, wenn ein Dialog von onCreate
zu schaffen, die geschieht, weil die Aktivität noch nicht erstellt, aber das kommt von einem Anruf von einem Menüobjekt und die appContext
Variable scheint, wie es richtig in die bevölkert Debugger.
Lösung
Statt:
Context appContext = this.getApplicationContext();
Sie sollten einen Zeiger auf die Aktivität verwenden Sie sind in (wahrscheinlich this
).
ich dies auch heute gebissen wurde, das lästige Teil ist die getApplicationContext()
ist wörtlich aus developer.android.com: (
Andere Tipps
Sie können ein Anwendungsfenster / Dialog über einen Kontext angezeigt werden, die keine Aktivität ist. Versuchen Sie eine gültige Aktivität Referenz geben
Ditto auf der getApplicationContext Sache.
Die Dokumente auf der Android-Website sagen, es zu benutzen, aber es funktioniert nicht ... grrrrr :-P
Just tun:
dialog = new Dialog(this);
"this" ist in der Regel Ihre Aktivität, von dem Sie den Dialog starten.
Android Dokumente schlagen getApplicationContext zu verwenden ();
, aber es wird nicht anstelle dieser Nutzung Ihre aktuelle Tätigkeit arbeiten, während AlertDialog.Builder oder Alertdialog oder Dialog Instanziieren ...
Beispiel:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
oder
AlertDialog.Builder builder = new AlertDialog.Builder((Your Activity).this);
Statt getApplicationContext()
, benutzen Sie einfach ActivityName.this
Ich hatte ein ähnliches Problem, bei dem ich so einem anderen Klasse etwas hatte:
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();
}
}
hat gut funktioniert die meiste Zeit, aber manchmal abgestürzt es mit dem gleichen Fehler. Dann merke ich, dass in MyActivity
I had ...
public class MyActivity extends Activity {
public static Something something;
public void someMethod() {
if (something==null) {
something=new Something(this);
}
}
}
Weil ich das Objekt als static
hielt, ein zweiter Durchlauf des Codes noch wurde die ursprüngliche Version des Objekts zu halten, und damit immer noch unter Bezugnahme auf die ursprüngliche Activity
, das nicht lange existiert.
Dumme dumme Fehler, vor allem weil ich wirklich nicht das Objekt als static
in erster Linie werden musste halten ...
Einfach in verändern
AlertDialog.Builder alert_Categoryitem =
new AlertDialog.Builder(YourActivity.this);
Anstelle von
AlertDialog.Builder alert_Categoryitem =
new AlertDialog.Builder(getApplicationContext());
Eine andere Lösung ist es, den Fenstertyp auf ein System Dialog zu setzen:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Dies erfordert die SYSTEM_ALERT_WINDOW
Erlaubnis:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Wie die docs sagen:
sollten nur sehr wenige Anwendungen, die diese Erlaubnis verwenden; Diese Fenster sind für System-Level-Interaktion mit dem Benutzer.
Dies ist eine Lösung, die Sie sollten nur verwendet werden, wenn Sie einen Dialog benötigen, die nicht auf eine Tätigkeit gebunden sind.
Verwenden Sie getApplicationContext()
nicht erklären dialouge
Verwenden Sie immer this
oder Ihre activity.this
Das ist für mich gearbeitet -
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();
Mit
ActivityName.this
Für verschachtelte Dialoge dieses Problem sehr häufig, es funktioniert, wenn
AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this);
wird verwendet, anstelle von
mDialogBuilder = new AlertDialog.Builder(getApplicationContext);
diese Alternative.
Sie können dies auch tun
public class Example extends Activity {
final Context context = this;
final Dialog dialog = new Dialog(context);
}
Das ist für mich gearbeitet !!
Wie gesagt, müssen Sie eine Tätigkeit als Rahmen für den Dialog, die Verwendung „YourActivity.this“ für einen statischen Kontext oder überprüfen hier wie eine dynamische in einem sicheren Modus verwenden
Versuchen dialog
Fensters Typ
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Vergessen Sie nicht die Erlaubnis android.permission.SYSTEM_ALERT_WINDOW
verwenden
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);
// }
});
}
Text hier: -
verwenden diese Option, um activity
Kontext für progressdialog
progressdialog = new ProgressDialog(Splash.this);
oder progressdialog = new ProgressDialog(this);
verwenden diese Option, um Anwendungskontext für BroadcastListener
nicht für progressdialog
.
progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
Die beste und sicherste Weg, um eine ‚ProgressDialog‘ in einem AsyncTask zu zeigen, Speicherverlust Problem zu vermeiden, ist ein ‚Handler‘ mit Looper.main () zu verwenden.
private ProgressDialog tProgressDialog;
dann in der 'onCreate'
tProgressDialog = new ProgressDialog(this);
tProgressDialog.setMessage(getString(R.string.loading));
tProgressDialog.setIndeterminate(true);
Jetzt r Sie mit dem Setup-Teil getan. Nun rufen 'Showprogress ()' und 'hideProgress ()' in 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);
}