web-dev-qa-db-de.com

Unterschied zwischen getContext (), getApplicationContext (), getBaseContext () und "this"

Was ist der Unterschied zwischen getContext(), getApplicationContext(), getBaseContext() und "this"?

Obwohl dies eine einfache Frage ist, kann ich den grundlegenden Unterschied zwischen ihnen nicht verstehen. Bitte geben Sie nach Möglichkeit einige einfache Beispiele an.

522
iCurious
  • View.getContext() : Gibt den Kontext zurück, in dem die Ansicht gerade ausgeführt wird. Normalerweise die aktuell aktive Aktivität.

  • Activity.getApplicationContext() : Gibt den Kontext für die gesamte Anwendung zurück (den Prozess, in dem alle Aktivitäten ausgeführt werden). Verwenden Sie dies anstelle des aktuellen Aktivitätskontexts, wenn Sie einen Kontext benötigen, der mit dem Lebenszyklus der gesamten Anwendung und nicht nur mit der aktuellen Aktivität verknüpft ist.

  • ContextWrapper.getBaseContext() : Wenn Sie Zugriff auf einen Kontext aus einem anderen Kontext heraus benötigen, verwenden Sie einen ContextWrapper. Auf den Kontext, auf den in diesem ContextWrapper verwiesen wird, wird über getBaseContext () zugegriffen.

504
Alexander Lucas

Die meisten Antworten beziehen sich bereits auf getContext() und getApplicationContext(), aber getBaseContext () wird selten erklärt.

Die Methode getBaseContext() ist nur relevant, wenn Sie eine ContextWrapper haben. Android stellt eine ContextWrapper Klasse bereit, die um eine vorhandene Context erstellt wird.

ContextWrapper wrapper = new ContextWrapper(context);

Der Vorteil der Verwendung von ContextWrapper besteht darin, dass Sie das Verhalten ändern können, ohne den ursprünglichen Kontext zu ändern. Wenn Sie beispielsweise eine Aktivität namens myActivity haben, können Sie View mit einem anderen Thema als myActivity erstellen:

ContextWrapper customTheme = new ContextWrapper(myActivity) {
  @Override
  public Resources.Theme getTheme() { 
    return someTheme;
  }
}
View myView = new MyView(customTheme);

ContextWrapper ist sehr leistungsfähig, da Sie damit die meisten von Context bereitgestellten Funktionen außer Kraft setzen können, einschließlich Code für den Zugriff auf Ressourcen (z. B. openFileInput(), getString()) und für die Interaktion mit anderen Komponenten (z. B. sendBroadcast(), registerReceiver()), fordert Berechtigungen an (z. B. checkCallingOrSelfPermission()) und löst Dateisystemspeicherorte auf (z. B. getFilesDir()). ContextWrapper ist sehr nützlich, um geräte-/versionsspezifische Probleme zu umgehen oder einmalige Anpassungen an Komponenten wie Ansichten vorzunehmen, die einen Kontext erfordern.

Die Methode getBaseContext () kann verwendet werden, um auf den "Basis" -Kontext zuzugreifen, den ContextWrapper umgibt. Möglicherweise müssen Sie auf den "Basis" -Kontext zugreifen, um beispielsweise zu überprüfen, ob es sich um ein Service, Activity oder Application handelt:

public class CustomToast {
  public void makeText(Context context, int resId, int duration) {
    while (context instanceof ContextWrapper) {
      context = context.baseContext();
    }
    if (context instanceof Service)) {
      throw new RuntimeException("Cannot call this from a service");
    }
    ...
  }
}

Oder wenn Sie die "entpackte" Version einer Methode aufrufen müssen:

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}
76
Mike Laren

getApplicationContext () - Gibt den Kontext für alle Aktivitäten zurück, die in der Anwendung ausgeführt werden.

getBaseContext () - Wenn Sie über einen anderen Kontext in der Anwendung auf den Kontext zugreifen möchten, können Sie darauf zugreifen.

getContext () - Gibt nur die aktuelle laufende Aktivität der Kontextansicht zurück.

38
Jay Patel

Context bietet Informationen zu Actvity oder Application neu erstellten Komponenten.

Relevant Context sollte für neu erstellte Komponenten bereitgestellt werden (egal ob Anwendungskontext oder Aktivitätskontext)

Da Activity eine Unterklasse von Context ist, kann man this verwenden, um den Kontext dieser Aktivität abzurufen

28
tez

Die Frage "Was ist der Kontext?" Ist eine der schwierigsten Fragen im Android Universum.

Der Kontext definiert Methoden, die auf Systemressourcen zugreifen, die statischen Ressourcen der Anwendung abrufen, Berechtigungen überprüfen, UI-Manipulationen durchführen und vieles mehr. Im Wesentlichen ist Context ein Beispiel für das Anti-Muster von God Object in der Produktion.

Wenn es darum geht, welche Art von Context wir verwenden sollen, wird es sehr kompliziert, da der Hierarchiebaum der Context -Unterklassen, abgesehen davon, dass er ein Gott-Objekt ist, das Liskov-Substitutionsprinzip brutal verletzt.

Dieser Blog-Beitrag versucht, die Anwendbarkeit von Context Klassen in verschiedenen Situationen zusammenzufassen.

Lassen Sie mich der Vollständigkeit halber die Haupttabelle aus diesem Beitrag kopieren:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | Application | Activity | Service | ContentProvider | BroadcastReceiver |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
| Show a Dialog              | NO          | YES      | NO      | NO              | NO                |
| Start an Activity          | NO¹         | YES      | NO¹     | NO¹             | NO¹               |
| Layout Inflation           | NO²         | YES      | NO²     | NO²             | NO²               |
| Start a Service            | YES         | YES      | YES     | YES             | YES               |
| Bind to a Service          | YES         | YES      | YES     | YES             | NO                |
| Send a Broadcast           | YES         | YES      | YES     | YES             | YES               |
| Register BroadcastReceiver | YES         | YES      | YES     | YES             | NO³               |
| Load Resource Values       | YES         | YES      | YES     | YES             | YES               |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
  1. Eine Anwendung KANN von hier aus eine Aktivität starten, es muss jedoch eine neue Aufgabe erstellt werden. 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 wird mit dem Standardthema für das System durchgeführt, auf dem Sie ausgeführt werden, und nicht mit dem, was in Ihrer Anwendung definiert ist.
  3. Zulässig, wenn der Empfänger den Wert null hat, der zum Abrufen des aktuellen Werts einer dauerhaften Sendung in Android 4.2 und höher verwendet wird.

screenshot

21
Vasiliy

Ein Stück UML-Diagramm des Kontexts

enter image description here

9
yoAlex5

Von diesem docs

Ich habe verstanden, dass Sie verwenden sollten:

Versuchen Sie, die Kontextanwendung anstelle einer Kontextaktivität zu verwenden

1
mehmet

getApplicationContext ()

dies wird für die Anwendungsebene verwendet und bezieht sich auf alle Aktivitäten.

getContext () und getBaseContext ()

ist höchstwahrscheinlich gleich. es werden nur aktuelle aktivitäten berücksichtigt die live sind.

this

bezieht sich immer auf das aktuelle Klassenobjekt.

0
Jatin Bansal