getApplicationContext()
ist fast immer falsch. Frau Hackborn (ua) haben sehr deutlich gewesen , dass Sie nur verwenden , getApplicationContext()
wenn Sie wissen , warum Sie verwenden getApplicationContext()
und nur , wenn Sie benötigen , um den EinsatzgetApplicationContext()
.
Um ehrlich zu sein, verwenden "einige Programmierer" getApplicationContext()
(oder getBaseContext()
in geringerem Maße), weil ihre Java-Erfahrung begrenzt ist. Sie implementieren eine innere Klasse (z. B. eine OnClickListener
für eine Button
in einer Activity
) und benötigen eine Context
. Anstatt zu benutzen MyActivity.this
, um an die äußere Klasse zu gelangen this
, benutzen sie getApplicationContext()
oder getBaseContext()
um eine zu bekommenContext
Objekt zu erhalten.
Sie verwenden es nur , getApplicationContext()
wenn Sie wissen, dass Sie eine Context
für etwas benötigen , das möglicherweise länger lebt als jedes andere, das Context
Ihnen wahrscheinlich zur Verfügung steht. Zu den Szenarien gehören:
Verwenden getApplicationContext()
Sie diese Option, wenn Sie etwas benötigen, das an einen Context
globalen Gültigkeitsbereich gebunden ist . Ich verwende getApplicationContext()
zum Beispiel in WakefulIntentService
, damit die Statik WakeLock
für den Dienst verwendet wird. Da das WakeLock
statisch ist und ich ein brauche Context
, um es PowerManager
zu erstellen, ist es am sichersten zu verwenden getApplicationContext()
.
Verwenden getApplicationContext()
Sie diese Option , wenn Sie an a Service
von a binden Activity
, wenn Sie das ServiceConnection
(dh das Handle an die Bindung) zwischen Activity
Instanzen über übergeben möchten onRetainNonConfigurationInstance()
. Android verfolgt intern Bindungen über diese ServiceConnections
und enthält Verweise auf Contexts
diejenigen, die die Bindungen erstellen. Wenn Sie von der binden Activity
, hat die neue Activity
Instanz einen Verweis auf den, ServiceConnection
der einen impliziten Verweis auf den alten hat Activity
, und der alte Activity
kann nicht durch Müll gesammelt werden.
Einige Entwickler verwenden benutzerdefinierte Unterklassen von Application
für ihre eigenen globalen Daten, über die sie abrufen getApplicationContext()
. Das ist sicherlich möglich. Ich bevorzuge statische Datenelemente, wenn Sie aus keinem anderen Grund nur ein benutzerdefiniertes Application
Objekt haben können. Ich habe eine App mit einem benutzerdefinierten Application
Objekt erstellt und fand es schmerzhaft. Frau Hackborn stimmt dieser Position ebenfalls zu .
Hier sind Gründe , warum nicht zu verwenden , getApplicationContext()
wohin Sie gehen:
Es ist nicht vollständig Context
und unterstützt alles, was es Activity
tut. Verschiedene Dinge, die Sie damit versuchen werden, schlagen Context
fehl, hauptsächlich im Zusammenhang mit der GUI .
Es kann zu Speicherlecks führen, wenn das Context
from getApplicationContext()
an etwas festhält, das durch Ihre Aufrufe erstellt wurde und das Sie nicht bereinigen. Mit einem Activity
, wenn es an etwas festhält Activity
, spült auch alles andere aus , sobald der Müll eingesammelt ist. Das Application
Objekt bleibt für die Lebensdauer Ihres Prozesses erhalten.
getApplicationContext()
wenn Sie genau wissen , warum Sie es in einer bestimmten Situation benötigen. Ein Layout aufblasen? Verwenden Sie die Aktivität. Bindung an einen Dienst, bei dem Sie diese Bindung benötigen, um eine Konfigurationsänderung zu überstehen? Verwenden SiegetApplicationContext()
, damit die Bindung nicht an dieActivity
Instanz gebunden ist .Ich denke, es gibt eine Menge Dinge, die auf der SDK-Site schlecht dokumentiert sind. Dies ist eine davon. Die Behauptung, die ich machen werde, ist, dass es anscheinend besser ist, standardmäßig einen Anwendungskontext zu verwenden und einen Aktivitätskontext nur dann zu verwenden, wenn Sie es wirklich brauchen. Der einzige Ort, an dem ich jemals gesehen habe, dass Sie einen Aktivitätskontext benötigen, ist ein Fortschrittsdialog. SBERG412 behauptet, dass Sie einen Aktivitätskontext für eine Toastnachricht verwenden müssen, die Android-Dokumente zeigen jedoch deutlich, dass ein Anwendungskontext verwendet wird. Aufgrund dieses Google-Beispiels habe ich immer den Anwendungskontext für Toasts verwendet. Wenn dies falsch ist, hat Google den Ball hier abgelegt.
Hier ist mehr zum Nachdenken und Überprüfen:
Für eine Toastnachricht verwendet der Google Dev Guide den Anwendungskontext und sagt ausdrücklich, dass er verwendet werden soll: Toastbenachrichtigungen
Im Abschnitt "Dialoge" des Dev-Handbuchs sehen Sie, dass ein AlertDialog.Builder den Anwendungskontext verwendet und der Fortschrittsbalken einen Aktivitätskontext. Dies wird von Google nicht erklärt. Dialoge
Ein guter Grund für die Verwendung des Anwendungskontexts scheint zu sein, wenn Sie Konfigurationsänderungen wie eine Orientierungsänderung behandeln und Objekte beibehalten möchten, die einen Kontext wie Ansichten benötigen. Wenn Sie hier suchen: Laufzeitänderungen Verwendung eines Aktivitätskontexts, der zu einem Leck führen kann, ist Vorsicht geboten. Dies kann mit einem Anwendungskontext mit den Ansichten vermieden werden, die beibehalten werden sollen (zumindest ist das mein Verständnis). In einer App, die ich schreibe, beabsichtige ich, einen Anwendungskontext zu verwenden, da ich versuche, einige Ansichten und andere Dinge bei einer Orientierungsänderung beizubehalten, und ich möchte weiterhin, dass die Aktivität bei Orientierungsänderungen zerstört und neu erstellt wird. Daher muss ich einen App-Kontext verwenden, um keinen Speicherverlust zu verursachen (siehe Vermeiden von Speicherverlusten) ). Mir scheint, es gibt viele gute Gründe, den Anwendungskontext anstelle eines Aktivitätskontexts zu verwenden, und für mich scheint es fast so, als würden Sie ihn häufiger als einen Aktivitätskontext verwenden. Das scheinen viele Android-Bücher zu tun, und genau das tun viele der Google-Beispiele, die ich gesehen habe.
Die Google-Dokumentation lässt den Eindruck entstehen, dass die Verwendung des Anwendungskontexts in den meisten Fällen vollkommen in Ordnung ist und tatsächlich häufiger als die Verwendung eines Aktivitätskontexts in ihren Beispielen (zumindest in den Beispielen, die ich gesehen habe). Wenn es wirklich so ein Problem ist, den Anwendungskontext zu verwenden, muss Google dies wirklich stärker betonen. Sie müssen es klarstellen und einige ihrer Beispiele wiederholen. Ich würde dies nicht nur unerfahrenen Entwicklern vorwerfen, da die Behörde (Google) es wirklich so aussehen lässt, als sei es kein Problem, Anwendungskontexte zu verwenden.
quelle
Ich habe diese Tabelle als Anleitung für die Verwendung der verschiedenen Kontexttypen verwendet, z. B. Anwendungskontext (dh :)
getApplicationContext()
und Aktivitätskontext , auch BroadcastReceiver-Kontext :Alle Verdienste gehen an den ursprünglichen Autor hier für weitere Informationen.
quelle
Es gibt zwei Arten von Kontext:
Der Anwendungskontext ist mit der Anwendung verknüpft und bleibt während der gesamten Lebensdauer der Anwendung gleich - er ändert sich nicht. Wenn Sie also Toast verwenden, können Sie den Anwendungskontext oder sogar den Aktivitätskontext (beide) verwenden, da Toast von überall in Ihrer Anwendung angezeigt werden kann und nicht an ein bestimmtes Fenster angehängt ist. Es gibt jedoch viele Ausnahmen. Eine Ausnahme ist, wenn Sie den Aktivitätskontext verwenden oder übergeben müssen.
Der Aktivitätskontext ist mit der Aktivität verknüpft und kann zerstört werden, wenn die Aktivität zerstört wird. Es kann mehrere Aktivitäten (mehr als wahrscheinlich) mit einer einzigen Anwendung geben. Und manchmal benötigen Sie unbedingt das Aktivitätskontext-Handle. Wenn Sie beispielsweise eine neue Aktivität starten, müssen Sie den Aktivitätskontext in seiner Absicht verwenden, damit die neue Startaktivität in Bezug auf den Aktivitätsstapel mit der aktuellen Aktivität verbunden ist. Sie können jedoch auch den Kontext der Anwendung verwenden, um eine neue Aktivität zu starten. Anschließend müssen Sie das Flag setzen
Intent.FLAG_ACTIVITY_NEW_TASK
, um sie als neue Aufgabe zu behandeln.Betrachten wir einige Fälle:
MainActivity.this
bezieht sich auf den MainActivity-Kontext, der die Activity-Klasse erweitert, aber die Basisklasse (Aktivität) erweitert auch die Context-Klasse, sodass sie zum Anbieten des Aktivitätskontexts verwendet werden kann.getBaseContext()
bietet Aktivitätskontext.getApplication()
bietet Anwendungskontext.getApplicationContext()
bietet auch Anwendungskontext.Weitere Informationen finden Sie unter diesem Link .
quelle
downloadmanager
und wenn das fertige Signal empfangen wird, sollte ein Dialogfeld angezeigt werden, z. B. "Was möchten Sie mit diesem Download tun?". Meine (Hack-) Lösung speichert die aktuellsteActivity
in einerstatic
Application
Klasse und fordert die aktuelle an,Activity
wenn der Download abgeschlossen ist. Ich bezweifle jedoch, dass dies die richtige Implementierung ist. TL; DR Wie kann AlertDialog irgendwo in der App angezeigt werden?Ich habe mich gefragt, warum ich den Anwendungskontext nicht für jede unterstützte Operation verwenden soll. Am Ende wird die Wahrscheinlichkeit eines Speicherverlusts und einer fehlenden Nullprüfung für getContext () oder getActivity () verringert (wenn ein injizierter Anwendungskontext verwendet oder durch eine statische Methode von Application erfasst wird). Aussagen, wie die von Frau Hackborn , den Anwendungskontext nur bei Bedarf zu verwenden, scheinen für mich nicht überzeugend zu sein, ohne eine Erklärung dafür zu haben. Aber es scheint, dass ich ein Unkleid gefunden habe, warum:
Da nicht garantiert werden kann, dass alle in der folgenden Tabelle vom Anwendungskontext unterstützten Vorgänge auf allen Android-Geräten funktionieren!
quelle
Zwei gute Beispiele dafür, wann Sie den Aktivitätskontext im Vergleich zum Anwendungskontext verwenden sollten, sind das Anzeigen einer Toastnachricht oder einer integrierten Dialognachricht, da die Verwendung des Anwendungskontexts eine Ausnahme verursacht:
oder
Beide benötigen Informationen aus dem Aktivitätskontext, die nicht im Anwendungskontext bereitgestellt werden.
quelle
Anwendungskontext live, bis Ihre Anwendung nur noch aktiv ist und nicht vom Aktivitätslebenszyklus abhängt, sondern der Kontext das Objekt langlebig hält . Wenn das Objekt, das Sie temporär verwenden, in dieser Zeit den Anwendungskontext und den Aktivitätskontext verwendet, wird der Anwendungskontext vollständig verwendet.
quelle