Unterschied zwischen Aktivitätskontext und Anwendungskontext

233

Das hat mich verblüfft, ich habe dies im Android 2.1-r8 SDK verwendet:

ProgressDialog.show(getApplicationContext(), ....);

und auch in

Toast t = Toast.makeText(getApplicationContext(),....);

mit getApplicationContext()Abstürzen beide ProgressDialogund Toast.... was mich zu dieser Frage führt:

Was sind die tatsächlichen Unterschiede zwischen einem Aktivitätskontext und einem Anwendungskontext, obwohl der Wortlaut "Kontext" geteilt wird?

t0mm13b
quelle
Dies ist, was ich gefunden habe stackoverflow.com/questions/1561803/… ....
t0mm13b
14
Dies sollte helfen, einige Dinge zu klären: Kontext, welcher Kontext?
toobsco42

Antworten:

250

Sie sind beide Instanzen des Kontexts , aber die Anwendungsinstanz ist an den Lebenszyklus der Anwendung gebunden, während die Aktivitätsinstanz an den Lebenszyklus einer Aktivität gebunden ist. Somit haben sie Zugriff auf verschiedene Informationen über die Anwendungsumgebung.

Wenn Sie die Dokumente unter getApplicationContext lesen , sollten Sie diese nur verwenden, wenn Sie einen Kontext benötigen, dessen Lebenszyklus vom aktuellen Kontext getrennt ist. Dies gilt in keinem Ihrer Beispiele.

Der Aktivitätskontext enthält vermutlich einige Informationen über die aktuelle Aktivität, die zum Abschließen dieser Aufrufe erforderlich ist. Wenn Sie die genaue Fehlermeldung anzeigen, können Sie möglicherweise genau angeben, was benötigt wird.

Verwenden Sie im Allgemeinen den Aktivitätskontext, es sei denn, Sie haben einen guten Grund, dies nicht zu tun.

Cheryl Simon
quelle
1
Ich habe eine 'java.lang.reflect.InvocationTargetException' erhalten getApplicationContext, wenn ich interessanterweise verwendet habe, als ich zu gewechselt habe this, es nicht abgestürzt ist und wie erwartet funktioniert hat. Wenn also beide Instanzen von Context sind, warum funktioniert man dann nicht und der andere tut? Diese Informationen werden anderen helfen, hoffe ich ... :) Danke für Ihre schnelle Antwort ...
t0mm13b
2
Ich müsste den vollständigen Stacktrace für Ausnahmen sehen, um etwas sagen zu können. Wie gesagt, die Kontextinstanzen haben jedoch unterschiedliche Informationen. Um einen Dialog oder Toast auf dem Bildschirm anzuzeigen, sind vermutlich Informationen zu der Aktivität erforderlich, über die nur die Aktivitätsinstanz verfügt.
Cheryl Simon
73
Ich würde sagen, verwenden Sie den App-Kontext, es sei denn, Sie haben nicht auch einen guten Grund (dh für Dialoge oder Toasts). Es ist ziemlich einfach, in Aktivitätskontexten in verschiedenen Situationen auf Speicherlecks zu stoßen
Dori
10
Dave Smith hat einen sehr guten Blogeintrag zum Verständnis der Verwendung von Kontext veröffentlicht, siehe hier . Stellen Sie sicher, dass Sie auch die Kommentare lesen!
ChrLipp
1
Die Sache ist, dass sogar Dianna Hackborn empfiehlt, Aktivitätskontext zu verwenden. stackoverflow.com/questions/5228160/… Aber sie scheint sich darüber nicht ganz sicher zu sein.
JacksOnF1re
177

Ich fand diese Tabelle sehr nützlich, um zu entscheiden, wann verschiedene Arten von Kontexten verwendet werden sollen:

Geben Sie hier die Bildbeschreibung ein

  1. Eine Anwendung KANN von hier aus eine Aktivität starten, erfordert jedoch die Erstellung einer neuen Aufgabe. Dies passt möglicherweise zu bestimmten Anwendungsfällen, kann jedoch zu nicht standardmäßigen Backstack-Verhaltensweisen in Ihrer Anwendung führen und wird im Allgemeinen nicht empfohlen oder als bewährte Methode angesehen.
  2. Dies ist legal, aber die Inflation erfolgt mit dem Standardthema für das System, auf dem Sie ausgeführt werden, und nicht mit dem, was in Ihrer Anwendung definiert ist.
  3. Erlaubt, wenn der Empfänger null ist, was zum Abrufen des aktuellen Werts einer Sticky-Sendung unter Android 4.2 und höher verwendet wird.

Originalartikel hier .

CommonSenseCode
quelle
Was ist mit den Ressourcen? Ich denke, Sie sollten es besser zu Ihrem Tisch hinzufügen. und Sie können mit dem Anwendungskontext auf Ressourcen zugreifen.
Amir Ziarati
Wir können die Aktivität aus dem Anwendungskontext starten
Duy Phan
Artikel kann auch hier gefunden werden: wundermanthompsonmobile.com/2013/06/context
Lifes
34

Dies ist offensichtlich ein Mangel des API-Designs. Erstens sind Aktivitätskontext und Anwendungskontext völlig unterschiedliche Objekte, daher sollten die Methodenparameter, in denen der Kontext verwendet wird, ApplicationContextoder Activitydirekt verwendet werden, anstatt den Kontext der übergeordneten Klasse zu verwenden. Zweitens sollte das Dokument angeben, welcher Kontext verwendet werden soll oder nicht.

lucas
quelle
25
Stimme voll und ganz zu. Google ließ den Ball auf diesen fallen. Es ist ein komplettes Durcheinander.
Søren Boisen
@ SørenBoisen android sdk ist ein komplettes Durcheinander
CommonSenseCode
Sie sind sich des Chaos bewusst und sind sich sicher, dass sie Schwierigkeiten haben, so viel wie möglich zu reparieren.
Pasignatur
15

Der Grund, den ich denke, ist, dass er ProgressDialogan die Aktivität angehängt ist, die das unterstützt, ProgressDialogda der Dialog nicht bleiben kann, nachdem die Aktivität zerstört wurde. Daher muss er übergeben werden this(ActivityContext), der auch mit der Aktivität zerstört wird, während der ApplicationContext auch nach dem Abrufen der Aktivität erhalten bleibt zerstört.

user2779311
quelle
3

Verwenden Sie getApplicationContext (), wenn Sie etwas benötigen, das an einen Kontext gebunden ist, der selbst einen globalen Gültigkeitsbereich hat.

Wenn Sie Activity verwenden, verfügt die neue Activity-Instanz über eine Referenz, die implizit auf die alte Activity verweist, und die alte Activity kann nicht durch Müll gesammelt werden.

Dhiraj Himani
quelle
2

Ich denke, wenn alles einen Bildschirm zum Anzeigen benötigt (Schaltfläche, Dialog, Layout ...), müssen wir Kontextaktivität verwenden, und alles benötigt keinen Bildschirm zum Anzeigen oder Verarbeiten (Toast, Servicetelefon, Kontakt ...) könnte einen Anwendungskontext verwenden

Dmobile
quelle
1

Sie können einen Unterschied zwischen den beiden Kontexten feststellen, wenn Sie Ihre App direkt vom Startbildschirm aus starten, und wenn Ihre App über eine gemeinsame Absicht von einer anderen App aus gestartet wird.

Hier ein praktisches Beispiel dafür, was "nicht standardmäßiges Backstack-Verhalten", das von @CommonSenseCode erwähnt wird, bedeutet:

Angenommen, Sie haben zwei Apps, die miteinander kommunizieren, App1 und App2 .

Starten Sie App2: MainActivity vom Launcher aus. Starten Sie dann von MainActivity aus App2: SecondaryActivity . Dort befinden sich beide Aktivitäten entweder im Aktivitätskontext oder im Anwendungskontext in derselben Aufgabe, und dies ist in Ordnung (vorausgesetzt, Sie verwenden alle Standardstartmodi und Absichtsflags). Sie können mit einem Druck auf MainActivity zurückkehren, und in den letzten Apps haben Sie nur eine Aufgabe.

Angenommen, Sie befinden sich jetzt in App1 und starten App2: MainActivity mit einer Freigabeabsicht (ACTION_SEND oder ACTION_SEND_MULTIPLE). Versuchen Sie dann von dort aus, App2: SecondaryActivity zu starten (immer mit allen Standardstartmodi und Absichtsflags). Was passiert ist:

  • Wenn Sie App2: SecondaryActivity mit Anwendungskontext unter Android <10 starten, können Sie nicht alle Aktivitäten in derselben Aufgabe starten . Ich habe es mit Android 7 und 8 versucht und die SecondaryActivity wird immer in einer neuen Aufgabe gestartet (ich denke, das liegt daran, dass App2: SecondaryActivity mit dem App2-Anwendungskontext gestartet wird, aber Sie kommen von App1 und haben die App2-Anwendung nicht direkt gestartet Vielleicht unter der Haube Android erkennen und FLAG_ACTIVITY_NEW_TASK verwenden). Dies kann je nach Ihren Bedürfnissen gut oder schlecht sein, da meine Bewerbung schlecht war.
    Unter Android 10 stürzt die App mit der Meldung ab, dass für das
    Aufrufen von startActivity () außerhalb eines Aktivitätskontexts das Flag FLAG_ACTIVITY_NEW_TASK erforderlich ist. Ist dies wirklich das, was Sie möchten?.
    Damit es unter Android 10 funktioniert, müssen Sie FALG_ACTIVITY_NEW_TASK verwenden und können nicht alle Aktivitäten in derselben Aufgabe ausführen.
    Wie Sie sehen können, ist das Verhalten zwischen Android-Versionen unterschiedlich, seltsam.

  • Wenn Sie App2: SecondaryActivity mit Aktivitätskontext starten, funktioniert alles gut und Sie können alle Aktivitäten in derselben Aufgabe ausführen, was zu einer linearen Backstack-Navigation führt.

Ich hoffe, ich habe einige nützliche Informationen hinzugefügt

DSoldo
quelle