In verschiedenen Teilen des Android-Codes habe ich gesehen:
public class MyActivity extends Activity {
public void method() {
mContext = this; // since Activity extends Context
mContext = getApplicationContext();
mContext = getBaseContext();
}
}
Ich kann jedoch keine vernünftige Erklärung dafür finden, welche vorzuziehen ist und unter welchen Umständen welche verwendet werden sollten.
Hinweise zur Dokumentation hierzu und Hinweise dazu, was bei Auswahl des falschen Dokuments möglicherweise kaputt geht, sind sehr willkommen.
android
android-context
Alnitak
quelle
quelle
Antworten:
Ich bin damit einverstanden, dass die Dokumentation in Bezug auf Kontexte in Android spärlich ist, aber Sie können einige Fakten aus verschiedenen Quellen zusammenstellen.
Dieser Blog-Beitrag im offiziellen Google Android-Entwicklerblog wurde hauptsächlich geschrieben, um Speicherlecks zu beheben. Er enthält jedoch auch einige gute Informationen zu Kontexten:
Wenn Sie den Artikel ein wenig weiter lesen, erfahren Sie mehr über den Unterschied zwischen den beiden und wann Sie möglicherweise die Verwendung des Anwendungskontexts (
Activity.getApplicationContext()
) anstelle des Aktivitätskontexts in Betracht ziehen möchtenthis
. Grundsätzlich ist der Anwendungskontext mit der Anwendung verknüpft und bleibt während des gesamten Lebenszyklus Ihrer App immer derselbe, wobei der Aktivitätskontext mit der Aktivität verknüpft ist und möglicherweise mehrmals zerstört werden kann, wenn die Aktivität während Änderungen der Bildschirmausrichtung und zerstört wird eine solche.Ich konnte wirklich nichts darüber finden, wann ich getBaseContext () verwenden sollte, außer einem Beitrag von Dianne Hackborn, einer der Google-Ingenieure, die am Android SDK arbeiten:
Das war aus einem Beitrag in der Newsgroup der Android-Entwickler. Vielleicht möchten Sie auch dort Ihre Frage stellen, da eine Handvoll Leute, die an Android arbeiten, diese Newsgroup überwachen und Fragen beantworten.
Insgesamt scheint es daher vorzuziehen, wenn möglich den globalen Anwendungskontext zu verwenden.
quelle
Don't use getBaseContext()
. Könnte jemand das klarstellen?Folgendes habe ich in Bezug auf die Verwendung von gefunden
context
:1).
Activity
Verwenden Sie in einem selbst dasthis
Aufblasen von Layouts und Menüs, das Registrieren von Kontextmenüs, das Instanziieren von Widgets, das Starten anderer Aktivitäten, das Erstellen neuer AktivitätenIntent
in einemActivity
, das Instanziieren von Einstellungen oder andere in einem verfügbare MethodenActivity
.Layout aufblasen:
Menü aufblasen:
Kontextmenü registrieren:
Widget instanziieren:
Starten Sie eine
Activity
:Präferenzen instanziieren:
2). Verwenden Sie für anwendungsweite Klassen,
getApplicationContext()
da dieser Kontext für die Lebensdauer der Anwendung vorhanden ist.Rufen Sie den Namen des aktuellen Android-Pakets ab:
Binden Sie eine anwendungsweite Klasse:
3) . Verwenden Sie für Listener und andere Arten von Android-Klassen (z. B. ContentObserver) eine Kontextsubstitution wie:
wo
this
odercontext
ist der Kontext einer Klasse (Aktivität usw.).Activity
Kontextsubstitution:Listener-Kontextsubstitution:
ContentObserver
Kontextsubstitution:4).
BroadcastReceiver
Verwenden Sie für (einschließlich Inline- / Embedded-Empfänger) den eigenen Kontext des Empfängers.Extern
BroadcastReceiver
:Inlined / Embedded
BroadcastReceiver
:5). Verwenden Sie für Dienste den eigenen Kontext des Dienstes.
6). Verwenden Sie für Toasts im Allgemeinen
getApplicationContext()
, aber verwenden Sie nach Möglichkeit den Kontext, der von einer Aktivität, einem Dienst usw. übergeben wurde.Verwenden Sie den Kontext der Anwendung:
Verwenden Sie den von einer Quelle übergebenen Kontext:
Und zuletzt nicht
getBaseContext()
wie von den Framework-Entwicklern von Android empfohlen verwenden.UPDATE: Fügen Sie
Context
Anwendungsbeispiele hinzu.quelle
OuterClass.this
; Siehe Kommentare in stackoverflow.com/questions/9605459/…Ich habe diesen Thread vor ein paar Tagen gelesen und mir die gleiche Frage gestellt. Meine Entscheidung nach dem Lesen war einfach: Verwenden Sie immer applicationContext.
Ich bin jedoch auf ein Problem gestoßen. Ich habe einige Stunden damit verbracht, es zu finden, und einige Sekunden, um es zu lösen ... (ein Wort ändern ...)
Ich verwende einen LayoutInflater, um eine Ansicht mit einem Spinner aufzublasen.
Hier sind also zwei Möglichkeiten:
1)
2)
Dann mache ich so etwas:
Was mir aufgefallen ist: Wenn Sie Ihr linearLayout mit dem applicationContext instanziiert haben, haben Sie beim Klicken auf den Drehfeld in Ihrer Aktivität eine nicht erfasste Ausnahme, die von der virtuellen Dalvik-Maschine stammt (nicht von Ihrem Code, deshalb habe ich viel ausgegeben Zeit zu finden, wo mein Fehler war ...).
Wenn Sie den baseContext verwenden, ist das in Ordnung, das Kontextmenü wird geöffnet und Sie können zwischen Ihren Auswahlmöglichkeiten wählen.
Hier ist meine Schlussfolgerung: Ich nehme an (ich habe es nicht weiter getestet), als der baseContext erforderlich ist, wenn Sie sich in Ihrer Aktivität mit contextMenu befassen ...
Der Test wurde mit API 8 codiert und auf einem HTC Desire, Android 2.3.3, getestet.
Ich hoffe, mein Kommentar hat Sie bisher nicht gelangweilt und wünsche Ihnen alles Gute. Viel Spaß beim Codieren ;-)
quelle
Erstens stimme ich zu, dass wir nach Möglichkeit Appcontext verwenden sollten. dann "dies" in Aktivität. Ich hatte noch nie einen Bedarf an Basecontext.
In meinen Tests können sie in den meisten Fällen ausgetauscht werden. In den meisten Fällen möchten Sie einen Kontext abrufen, indem Sie auf Dateien, Einstellungen, Datenbanken usw. zugreifen. Diese Daten werden schließlich als Dateien im privaten Datenordner Ihrer App (/ data / data /) wiedergegeben. Unabhängig davon, welchen Kontext Sie verwenden, werden sie demselben Ordner / denselben Dateien zugeordnet, sodass Sie in Ordnung sind.
Das habe ich beobachtet. Vielleicht gibt es Fälle, in denen Sie sie unterscheiden sollten.
quelle
In einigen Fällen können Sie den Aktivitätskontext über den Anwendungskontext verwenden, wenn Sie etwas in einem Thread ausführen. Wenn der Thread die Ausführung abgeschlossen hat und Sie das Ergebnis an die Aufruferaktivität zurückgeben müssen, benötigen Sie diesen Kontext mit einem Handler.
quelle
In einfachen Worten
getApplicationContext()
Wie der Methodenname andeutet, macht Ihre App auf anwendungsweite Details aufmerksam, auf die Sie von überall in der App zugreifen können. Sie können dies also nutzen, um die Servicebindung, die Broadcast-Registrierung usw.Application context
bis zum Beenden der App aufrechtzuerhalten.getActivity()
oderthis
macht Ihre App auf den aktuellen Bildschirm aufmerksam, auf dem auch die Details auf App-Ebene von angezeigt werdenapplication context
. Was auch immer Sie über den aktuellen Bildschirm wissen möchtenWindow
ActionBar
Fragementmanger
und in diesem Kontext verfügbar sind. Grundsätzlich undActivity
erweiternContext
. Dieser Kontext bleibt bestehen, bis die aktuelle Komponente (Aktivität) aktiv istquelle
Was ist ein Kontext? Ich persönlich stelle mir den Kontext jederzeit als den Status Ihrer Bewerbung vor. Der Anwendungskontext stellt eine globale oder Basiskonfiguration Ihrer Anwendung dar, auf der eine Aktivität oder ein Dienst aufbauen kann, und stellt eine Konfigurationsinstanz Ihrer Anwendung oder einen transitiven Status für diese Anwendung dar.
Wenn Sie sich die Quelle für android.content.Context ansehen, sehen Sie, dass Context eine abstrakte Klasse ist und die Kommentare zur Klasse wie folgt lauten:
Schnittstelle zu globalen Informationen über eine Anwendungsumgebung. Dies ist eine abstrakte Klasse, deren Implementierung vom Android-System bereitgestellt wird. Es ermöglicht den Zugriff auf
application-specific
Ressourcen und Klassen sowie das Aufrufen vonapplication-level
Vorgängen wie Starten von Aktivitäten, Senden und Empfangen von Absichten usw. Was ich davon wegnehme, ist, dass Context eine gemeinsame Implementierung für den Zugriff auf Anwendungsebene sowie auf Systemebene bietet Ressourcen. Ressourcen auf Anwendungsebene greifen möglicherweise auf Dinge wie String-Ressourcen[getResources()]
oder Assets zu,[getAssets()]
und Ressourcen auf Systemebene sind alles, mit denen Sie zugreifenContext.getSystemService().
Schauen Sie sich in der Tat die Kommentare zu den Methoden an und sie scheinen diesen Gedanken zu bekräftigen:
getSystemService()
: Geben Sie das Handle nachsystem-level
Namen an einen Dienst zurück. Die Klasse des zurückgegebenen Objekts hängt vom angeforderten Namen ab.getResources()
: Geben Sie eine Ressourceninstanz für das Paket Ihrer Anwendung zurück.getAssets()
: Geben Sie eine Ressourceninstanz für das Paket Ihrer Anwendung zurück. Es kann erwähnenswert sein, dass in der Klasse Context abstract alle oben genannten Methoden abstrakt sind! Nur eine Instanz von getSystemService (Class) verfügt über eine Implementierung, die eine abstrakte Methode aufruft. Dies bedeutet, dass die Implementierung für diese hauptsächlich von den implementierenden Klassen bereitgestellt werden sollte, zu denen gehören:In der API-Dokumentation sieht die Hierarchie der Klassen folgendermaßen aus:
Kontext
| - ContextWrapper
| - - Anwendung
| - - ContextThemeWrapper
| - - - - Aktivität
| - - Bedienung
| - - - IntentService
Da wir wissen, dass es
Context
selbst keinen Einblick gibt, gehen wir den Baum hinunter und schauen uns das anContextWrapper
und stellen fest, dass dort auch nicht viel ist. Da die Anwendung erweitert wirdContextWrapper
, gibt es dort auch nicht viel zu sehen, da sie die von bereitgestellte Implementierung nicht überschreibtContextWrapper
. Dies bedeutet, dass die Implementierung für Context vom Betriebssystem bereitgestellt und vor dem verborgen wirdAPI
. Sie können sich die konkrete Implementierung für Context ansehen, indem Sie sich die Quelle für die ContextImpl-Klasse ansehen.quelle
Ich habe dies nur verwendet und
getBaseContext
beim Toasten von einemonClick
(sehr grünen Noob auf Java und Android). Ich benutze dies, wenn mein Clicker direkt in der Aktivität ist undgetBaseContext
in einem anonymen inneren Clicker verwendet werden muss. Ich vermute, das ist so ziemlich der TrickgetBaseContext
, es gibt vielleicht den Kontext der Aktivität zurück, in der sich die innere Klasse versteckt.quelle
MyActivity.this
. Die Verwendung des von Ihnen beschriebenen Basiskontexts wird wahrscheinlich keine Probleme verursachen, ist jedoch falsch.