Differenza tra getContext (), getApplicationContext (), getBaseContext () e “this”


566

Qual è la differenza tra getContext(), getApplicationContext(), getBaseContext(), e " this"?

Sebbene questa sia una domanda semplice, non sono in grado di comprendere la differenza fondamentale tra di loro. Si prega di fornire alcuni esempi semplici, se possibile.


1
V'è un eccellente interessante resoconto nella prima risposta: stackoverflow.com/questions/1026973/...
ky1enamic

Risposte:


529
  • View.getContext(): Restituisce il contesto in cui è attualmente in esecuzione la vista. Di solito l'attività attualmente attiva.

  • Activity.getApplicationContext(): Restituisce il contesto per l'intera applicazione (il processo all'interno del quale sono in esecuzione tutte le attività). Utilizzalo al posto dell'attuale contesto di attività se hai bisogno di un contesto legato al ciclo di vita dell'intera applicazione, non solo dell'attuale attività.

  • ContextWrapper.getBaseContext(): Se è necessario accedere a un contesto da un altro contesto, utilizzare un ContextWrapper. È possibile accedere al contesto a cui si fa riferimento all'interno di ContextWrapper tramite getBaseContext ().


59
e che dire di "questo"?
CooL i3oY,

16
+ CooL i3oY stesso con getContext
Mikey

13
in realtà sono confuso che qual è la corretta definizione del contesto ??
Ravi,

11
"this" e getContext () sono entrambi uguali
KCRaju il

43
thise getContext()non sono sempre uguali, ad esempio nella classe Activity, è possibile utilizzarlo thisperché Activityeredita da Contextma il metodo getContext()non è nella Activityclasse. @mikedroid @KCRaju
nandan

92

La maggior parte delle risposte copre già getContext()e getApplicationContext()ma getBaseContext () viene raramente spiegato.

Il metodo getBaseContext()è rilevante solo quando hai un ContextWrapper. Android fornisce una ContextWrapperclasse creata attorno a un esistente Contextutilizzando:

ContextWrapper wrapper = new ContextWrapper(context);

Il vantaggio dell'uso di a ContextWrapperè che ti permette di "modificare il comportamento senza cambiare il contesto originale". Ad esempio, se hai un'attività chiamata, myActivitypuoi crearne una Viewcon un tema diverso da myActivity:

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

ContextWrapperè davvero potente perché consente di ignorare la maggior parte delle funzioni fornite Contextincludendo il codice per accedere alle risorse (ad es openFileInput(). getString()), interagire con altri componenti (ad es sendBroadcast(). registerReceiver()), richiedere autorizzazioni (ad es. checkCallingOrSelfPermission()) e risolvere i percorsi dei file system (ad es getFilesDir().). ContextWrapperè davvero utile per aggirare i problemi specifici di dispositivo / versione o applicare personalizzazioni una tantum a componenti come Viste che richiedono un contesto.

Il metodo getBaseContext () può essere utilizzato per accedere al contesto "base" che ContextWrapperavvolge. Potrebbe essere necessario accedere al contesto “base” se è necessario, ad esempio, verificare se si tratta di una Service, Activityo 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");
    }
    ...
  }
}

O se è necessario chiamare la versione "non scartata" di un metodo:

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

17
Direi che questa è la risposta più importante dopo una accettata.
0

4
Direi che l'esistenza di ContextWrapperè una delle peggiori decisioni mai prese dagli sviluppatori del framework Android. Quando si resero conto di aver creato un'intera famiglia di oggetti di Dio, invece di fare la cosa giusta e riformattare il codice verso la responsabilità singola, hanno aggiunto un brutto hack che ha permesso di cambiare il comportamento del contesto approfondendo l'albero dell'eredità. Cattiva ingegneria del software nella sua forma più brutta. Per quanto riguarda noi, sviluppatori, IMHO nessuno dovrebbe mai usare getBaseContext()o ContextWrapper. Se lo fai, è un enorme "odore di codice".
Vasiliy,

Mi piacerebbe vedere il CustomToastcodice completo . Ston :)))
Alston,

39

getApplicationContext () - Restituisce il contesto per tutte le attività in esecuzione nell'applicazione.

getBaseContext () - Se si desidera accedere al contesto da un altro contesto all'interno dell'applicazione, è possibile accedere.

getContext () - Restituisce la vista di contesto solo l'attività corrente in esecuzione.


1
Incorpora le lettere A e B nella tua definizione di contesto in un contesto, non è chiaro in nessuna risposta a quale contesto si accede.
Speriamo utile

30

La domanda "cos'è il contesto" è una delle domande più difficili nell'universo Android.

Il contesto definisce i metodi che accedono alle risorse di sistema, recuperano le risorse statiche dell'applicazione, controllano le autorizzazioni, eseguono manipolazioni dell'interfaccia utente e molto altro. In sostanza, Contextè un esempio dell'anti-pattern di God Object in produzione.

Quando si tratta di quale tipo di Contextutilizzo dovremmo usare, diventa molto complicato perché, a parte l'essere God Object, l'albero gerarchico delle Contextsottoclassi viola brutalmente il principio di sostituzione di Liskov.

Questo post sul blog tenta di sintetizzare l' Contextapplicabilità delle classi in diverse situazioni.

Consentitemi di copiare la tabella principale da quel post per completezza:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | 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. Un'applicazione PU start iniziare un'attività da qui, ma richiede la creazione di una nuova attività. Questo può adattarsi a casi d'uso specifici, ma può creare comportamenti di back stack non standard nell'applicazione e generalmente non è raccomandato o considerato una buona pratica.
  2. Questo è legale, ma l'inflazione verrà eseguita con il tema predefinito per il sistema su cui si sta eseguendo, non ciò che è definito nella propria applicazione.
  3. Consentito se il ricevitore è null, utilizzato per ottenere il valore corrente di una trasmissione permanente, su Android 4.2 e versioni successive.

immagine dello schermo


Ottimo post sul blog che hai collegato!
lejonl

28

Contextfornisce informazioni sui componenti appena creati Actvityo Application.

Rilevante Contextdovrebbe essere fornito ai componenti appena creati (se contesto dell'applicazione o contesto dell'attività)

Poiché Activityè una sottoclasse di Context, è possibile utilizzare thisper ottenere il contesto di quell'attività


Dov'è la tua spiegazione su baseContext?
IgorGanapolsky,

1

Da questi documenti

Ho capito che dovresti usare:

Prova a utilizzare l'applicazione di contesto anziché un'attività di contesto


0

getApplicationContext ()

questo è usato per il livello dell'applicazione e si riferisce a tutte le attività.

getContext () e getBaseContext ()

è molto probabilmente lo stesso. a questi si riferisce solo l'attività corrente che è in diretta.

Questo

fa sempre riferimento all'oggetto classe corrente.


0

A Contextè:

  • una classe astratta la cui implementazione è fornita dal sistema Android.
  • Consente l'accesso a risorse e classi specifiche dell'applicazione, nonché inviti a operazioni a livello di applicazione come l'avvio di attività, la trasmissione e la ricezione di intenti, ecc.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.