653 Stimmen

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 einige einfache Beispiele, wenn möglich.

604voto

Alexander Lucas Punkte 21761
  • View.getContext() : Gibt den Kontext zurück, in dem die Ansicht gerade läuft. Normalerweise die gerade aktive Aktivität.

  • Activity.getApplicationContext() : Gibt den Kontext für die gesamte Anwendung zurück (der Prozess, in dem alle Aktivitäten laufen). laufen). Verwenden Sie dies anstelle des aktuellen Activity-Kontextes, wenn Sie einen Kontext benötigen, der an den Lebenszyklus der gesamten Anwendung und nicht nur an die aktuellen Aktivität.

  • ContextWrapper.getBaseContext() : Wenn Sie Zugriff auf einen Context aus einem anderen Context heraus benötigen, verwenden Sie einen ContextWrapper. Der Context, auf den innerhalb dieses ContextWrappers verwiesen wird, wird über getBaseContext().

153voto

Mike Laren Punkte 7768

Die meisten Antworten decken bereits getContext() y getApplicationContext() sondern getBaseContext() wird selten erklärt.

Die Methode getBaseContext() ist nur relevant, wenn Sie eine ContextWrapper . Android bietet eine ContextWrapper Klasse, die um eine bestehende Context verwenden:

ContextWrapper wrapper = new ContextWrapper(context);

Der Vorteil der Verwendung eines ContextWrapper ist, dass man damit "das Verhalten ändern kann, ohne den ursprünglichen Kontext zu verändern". Wenn Sie zum Beispiel eine Aktivität namens myActivity kann dann eine View mit einem anderen Thema als myActivity :

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

ContextWrapper ist sehr leistungsfähig, weil es Ihnen erlaubt, die meisten Funktionen, die von Context einschließlich Code für den Zugriff auf Ressourcen (z. B. openFileInput() , getString() ), interagieren mit anderen Komponenten (z. B. sendBroadcast() , registerReceiver() ), beantragt Genehmigungen (z. B. checkCallingOrSelfPermission() ) und das Auflösen von Dateisystempositionen (z.B. getFilesDir() ). ContextWrapper ist sehr nützlich, um geräte-/versionsspezifische Probleme zu umgehen oder um einmalige Anpassungen an Komponenten wie Views vorzunehmen, die einen Kontext erfordern.

Die Methode getBaseContext() kann verwendet werden, um auf den "Basis"-Kontext zuzugreifen, den die ContextWrapper wickelt um. Möglicherweise müssen Sie auf den "Basis"-Kontext zugreifen, wenn Sie z. B. prüfen wollen, ob es sich um einen Service , Activity o Application :

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 "unverpackte" Version einer Methode aufrufen müssen:

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

47voto

Vasiliy Punkte 15663

Die Frage "Was ist Context" ist eine der schwierigsten Fragen im Android-Universum.

Context definiert Methoden, die auf Systemressourcen zugreifen, die statischen Assets der Anwendung abrufen, Berechtigungen prüfen, UI-Manipulationen durchführen und vieles mehr. Im Wesentlichen, Context ist ein Beispiel für ein God Object Anti-Pattern in der Produktion.

Wenn es darum geht, welche Art von Context verwenden sollten, wird es sehr kompliziert, denn abgesehen davon, dass es sich um ein Gottesobjekt handelt, ist der Hierarchiebaum von Context Unterklassen verstößt brutal gegen das Liskovsche Substitutionsprinzip.

Dieser Blogbeitrag (jetzt von Wayback Machine) versucht zusammenzufassen Context Klassen die Anwendbarkeit in verschiedenen Situationen.

Der Vollständigkeit halber möchte ich 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, aber sie erfordert, dass eine neue Aufgabe erstellt wird. Dies kann für bestimmte Anwendungsfälle geeignet sein, kann aber zu einem nicht standardmäßigen Backstack-Verhalten in Ihrer Anwendung führen und wird im Allgemeinen nicht empfohlen oder als gute Praxis angesehen.
  2. Dies ist legal, aber die Inflationierung erfolgt mit dem Standardthema für das System, auf dem Sie laufen, und nicht mit dem, was in Ihrer Anwendung definiert ist.
  3. Erlaubt, wenn der Empfänger null ist, was unter Android 4.2 und höher verwendet wird, um den aktuellen Wert eines Sticky Broadcasts zu erhalten.

screenshot

40voto

Jaykumar Patel Punkte 25455

getApplicationContext() - Gibt den Kontext für alle in der Anwendung laufenden Aktivitäten zurück.

getBaseContext() - Wenn Sie von einem anderen Kontext innerhalb der Anwendung auf Context zugreifen möchten, können Sie dies tun.

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

28voto

tez Punkte 4798

Context liefert Informationen über die Actvity o Application zu neu erstellten Komponenten.

Einschlägige Context sollte neu erstellten Komponenten zur Verfügung gestellt werden (ob Anwendungskontext oder Aktivitätskontext)

Desde Activity ist eine Unterklasse von Context kann man verwenden this um den Kontext dieser Aktivität zu erhalten

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X