Ich konnte keine zufriedenstellende Antwort darauf finden, also los geht's: Was ist los mit Activity/Service.getApplication()
undContext.getApplicationContext()
?
In unserer Anwendung geben beide dasselbe Objekt zurück. In einem Fall wird durch das ActivityTestCase
Verspotten der Anwendung jedoch das Verspotten getApplication()
zurückgegeben, es getApplicationContext
wird jedoch immer noch eine andere Kontextinstanz zurückgegeben (eine von Android injizierte). Ist das ein Fehler? Ist es absichtlich?
Ich verstehe den Unterschied überhaupt nicht. Gibt es Fälle außerhalb einer Testsuite, in denen beide Anrufe mit unterschiedlichen Objekten zurückkommen können? Wann und warum? Warum ist außerdem getApplication
auf Activity
und definiert Service
, aber nicht auf Context
? Sollte nicht immer eine gültige Anwendungsinstanz von überall verfügbar sein ?
Application
Objekt explizit erstellen .Antworten:
Sehr interessante Frage. Ich denke, es ist hauptsächlich eine semantische Bedeutung und kann auch historische Gründe haben.
Obwohl in aktuellen Implementierungen Android Aktivität und Dienstleistung,
getApplication()
undgetApplicationContext()
das gleiche Objekt zurück, gibt es keine Garantie , dass dies immer der Fall sein (beispielsweise in einer bestimmten Lieferanten - Implementierung).Wenn Sie also die Anwendungsklasse möchten, die Sie im Manifest registriert haben, sollten Sie sie niemals aufrufen
getApplicationContext()
und in Ihre Anwendung umwandeln, da es sich möglicherweise nicht um die Anwendungsinstanz handelt (die Sie offensichtlich mit dem Testframework erlebt haben).Warum gibt
getApplicationContext()
es überhaupt?getApplication()
ist nur in der Activity-Klasse und der Service-Klasse verfügbar, während siegetApplicationContext()
in der Context-Klasse deklariert ist.Das bedeutet tatsächlich eines: Wenn Sie Code in einen Rundfunkempfänger schreiben, der kein Kontext ist, sondern in seiner onReceive-Methode einen Kontext erhält, können Sie nur aufrufen
getApplicationContext()
. Dies bedeutet auch, dass Sie in einem BroadcastReceiver nicht garantiert Zugriff auf Ihre Anwendung haben.Wenn Sie sich den Android-Code ansehen, sehen Sie, dass eine Aktivität im Anhang einen Basiskontext und eine Anwendung erhält. Dies sind unterschiedliche Parameter.
getApplicationContext()
delegiert den Anruf anbaseContext.getApplicationContext()
.Eine weitere Sache: Die Dokumentation besagt, dass Sie in den meisten Fällen keine Unterklasse für die Anwendung benötigen sollten:
Ich weiß, dass dies keine genaue und präzise Antwort ist, aber beantwortet das trotzdem Ihre Frage?
quelle
android.app.Application
sind super Hilfe voll. Zum Beispiel hatte ich endlose Probleme beim Initialisieren der Datenbank. Einmal eingezogenApplication.onCreate
, funktionierte es wie ein Zauber. Jetzt mache ich alle systemweiten Initialisierungen inApplication
und würde ohne keine weitere App schreiben.Vergleiche
getApplication()
undgetApplicationContext()
.getApplication
gibt einApplication
Objekt , das Sie zu verwalten Ihre globalen Anwendungszustand und reagieren auf einige Geräte Situationen wie erlaubtonLowMemory()
undonConfigurationChanged()
.getApplicationContext
Gibt den globalen Anwendungskontext zurück. Der Unterschied zu anderen Kontexten besteht darin, dass beispielsweise ein Aktivitätskontext von Android zerstört (oder anderweitig nicht verfügbar gemacht) werden kann, wenn Ihre Aktivität endet. Der Anwendungskontext bleibt verfügbar, solange Ihr Anwendungsobjekt vorhanden ist (das nicht an ein bestimmtes Objekt gebunden istActivity
), sodass Sie ihn beispielsweise für Benachrichtigungen verwenden können , für die ein Kontext erforderlich ist, der für längere Zeiträume verfügbar und unabhängig von vorübergehenden UI-Objekten ist.Ich denke, es hängt davon ab, was Ihr Code tut, ob diese gleich sind oder nicht - obwohl ich bei normaler Verwendung erwarten würde, dass sie unterschiedlich sind.
quelle
Application
ist aContext
(es erbt davon) und zur Laufzeit geben beide Methoden dieselbe Instanz zurück. Was ist der Unterschied?Activity
Kontext und einemApplication
Kontext. Ich denke über den Unterschied zwischenApplication
(dem globalen, einzigartigen Anwendungskontext) und dem, wasgetApplicationContext
zurückkommt, nach. Letzteres war vor Android 1.6 tatsächlich nicht funktionsfähig; es kehrte immer zurücknull
.Es scheint mit Kontextumbruch zu tun zu haben. Die meisten abgeleiteten Klassen
Context
sind tatsächlich aContextWrapper
, die im Wesentlichen an einen anderen Kontext delegieren, möglicherweise mit Änderungen durch den Wrapper.Der Kontext ist eine allgemeine Abstraktion, die das Verspotten und Proxying unterstützt. Da viele Kontexte an ein Objekt mit begrenzter Lebensdauer wie z. B. a gebunden sind
Activity
, muss es eine Möglichkeit geben, einen längerlebigen Kontext zu erhalten, z. B. um sich für zukünftige Benachrichtigungen zu registrieren. Das wird erreicht durchContext.getApplicationContext()
. Eine logische Implementierung besteht darin, das globaleApplication
Objekt zurückzugeben, aber nichts hindert eine Kontextimplementierung daran, stattdessen einen Wrapper oder Proxy mit einer geeigneten Lebensdauer zurückzugeben.Aktivitäten und Dienstleistungen sind spezifischer mit einem
Application
Objekt verbunden. Die Nützlichkeit dieses, glaube ich, ist , dass Sie in dem Manifest einer benutzerdefinierten Klasse erstellen und registrieren können abgeleitetApplication
und sicher sein , dassActivity.getApplication()
oderService.getApplication()
werden , dass bestimmtes Objekt dieses speziellen Typen zurückgeben, die Sie Ihren abgeleitet werfen könnenApplication
Klasse und Verwendung für was auch immer kundenspezifischer Zweck.Mit anderen Worten, es
getApplication()
wird garantiert, dass einApplication
Objekt zurückgegeben wird, währendgetApplicationContext()
es frei ist, stattdessen einen Proxy zurückzugeben.quelle
Um die Frage zu beantworten, gibt getApplication () ein Anwendungsobjekt und getApplicationContext () ein Kontextobjekt zurück. Basierend auf Ihren eigenen Beobachtungen würde ich annehmen, dass der Kontext von beiden identisch ist (dh hinter den Kulissen ruft die Anwendungsklasse die letztere Funktion auf, um den Kontextteil der Basisklasse zu füllen, oder es findet eine gleichwertige Aktion statt). Es sollte eigentlich keine Rolle spielen, welche Funktion Sie aufrufen, wenn Sie nur einen Kontext benötigen.
quelle