696 Stimmen

Dialog mit der Meldung "Fenster kann nicht hinzugefügt werden - Token null ist nicht für eine Anwendung" mit getApplication() als Kontext

Meine Aktivität versucht, einen AlertDialog zu erstellen, der einen Kontext als Parameter erfordert. Dies funktioniert wie erwartet, wenn ich verwenden:

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

Allerdings bin ich misstrauisch bei der Verwendung von "this" als Kontext aufgrund des Potenzials für Speicherlecks, wenn Aktivität zerstört und neu erstellt wird, auch während etwas Einfaches wie eine Bildschirmdrehung. Von einer zugehöriger Beitrag im Blog der Android-Entwickler :

Es gibt zwei einfache Möglichkeiten, um kontextbezogene Speicherlecks zu vermeiden. Die offensichtlichste besteht darin, den Kontext nicht außerhalb seines eigenen Bereichs zu lassen. Das obige Beispiel zeigt den Fall einer statischen Referenz, aber innere Klassen und ihre implizite Referenz auf die äußere Klasse können ebenso gefährlich sein. Die zweite Lösung besteht darin, den Anwendungskontext zu verwenden. Dieser Kontext lebt so lange, wie Ihre Anwendung existiert und ist nicht vom Lebenszyklus der Aktivitäten abhängig. Wenn Sie planen, langlebige Objekte zu behalten, die einen Kontext benötigen, sollten Sie sich das Anwendungsobjekt merken. Sie können es leicht erhalten, indem Sie Context.getApplicationContext() oder Activity.getApplication() aufrufen.

Aber für die AlertDialog() weder getApplicationContext() o getApplication() ist als Context akzeptabel, da er die Ausnahme auslöst:

"Fenster kann nicht hinzugefügt werden - Token Null ist nicht für eine Anwendung"

nach Referenzen: 1 , 2 , 3 , usw.

Sollte dies also wirklich als "Fehler" betrachtet werden, da uns offiziell empfohlen wird, die Activity.getApplication() und trotzdem funktioniert es nicht wie versprochen?

Jim

1voto

josedlujan Punkte 4941

Wenn Ihr Dialog auf dem Adapter erstellt wird:

Übergeben Sie die Activity an den Adapter-Konstruktor:

adapter = new MyAdapter(getActivity(),data);

Empfangen auf dem Adapter:

 public MyAdapter(Activity activity, List<Data> dataList){
       this.activity = activity;
    }

Jetzt können Sie auf Ihrem Builder verwenden

            AlertDialog.Builder alert = new AlertDialog.Builder(activity);

1voto

G_V Punkte 2346

Nachdem Sie einen Blick auf die API geworfen haben, können Sie dem Dialog Ihre Aktivität oder getActivity übergeben, wenn Sie sich in einem Fragment befinden, und ihn dann mit dialog.dismiss() in den Rückgabemethoden zwangsweise bereinigen, um Lecks zu vermeiden.

Obwohl es nirgendwo explizit angegeben ist, scheint es, dass Sie den Dialog in den OnClickHandlern zurückgegeben werden, nur um dies zu tun.

0voto

us_david Punkte 3895

Hier ist, wie ich den gleichen Fehler für meine Anwendung behoben:
Hinzufügen der folgenden Zeile nach dem Erstellen des Dialogs:

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

Sie müssen keinen Kontext erwerben. Dies ist besonders nützlich, wenn Sie ein anderes Dialogfeld über dem aktuellen Dialogfeld aufklappen. Oder wenn es nicht bequem ist, einen Kontext zu erhalten.

Ich hoffe, dies kann Ihnen bei Ihrer App-Entwicklung helfen.

David

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X