Différence entre getContext (), getApplicationContext (), getBaseContext () et «this»

566

Quelle est la différence entre getContext(),getApplicationContext() , getBaseContext()et " this« ?

Bien que ce soit une question simple, je suis incapable de comprendre la différence fondamentale entre eux. Veuillez donner quelques exemples simples si possible.

iCurious
la source
1
Il y a un excellent résumé dans la première réponse: stackoverflow.com/questions/1026973/…
ky1enamic

Réponses:

529
  • View.getContext(): Renvoie le contexte dans lequel la vue est en cours d'exécution. Habituellement, l'activité actuellement active.

  • Activity.getApplicationContext(): Renvoie le contexte de l'application entière (le processus dans lequel toutes les activités s'exécutent). Utilisez-le à la place du contexte d'activité actuel si vous avez besoin d'un contexte lié au cycle de vie de l'application entière, et pas seulement de l'activité en cours.

  • ContextWrapper.getBaseContext(): Si vous avez besoin d'accéder à un contexte à partir d'un autre contexte, vous utilisez un ContextWrapper. Le contexte auquel l'intérieur de ContextWrapper fait référence est accessible via getBaseContext ().

Alexander Lucas
la source
59
et qu'en est-il de "ceci"?
CooL i3oY
16
+ CooL i3oY même avec getContext
Mikey
13
en fait je suis confus que quelle est la bonne définition du contexte ??
Ravi
11
"this" et getContext () sont les mêmes
KCRaju
43
thiset getContext()ne sont pas toujours les mêmes, par exemple dans la classe Activity, vous pouvez utiliser thiscar Activityhérite de Contextmais la méthode getContext()n'est pas dans la Activityclasse. @mikedroid @KCRaju
nandan
92

La plupart des réponses couvrent déjà getContext()et getApplicationContext()mais getBaseContext () est rarement expliqué.

La méthode getBaseContext()n'est pertinente que si vous en avez un ContextWrapper. Android fournit une ContextWrapperclasse qui est créée autour d'un existant en Contextutilisant:

ContextWrapper wrapper = new ContextWrapper(context);

L'avantage d'utiliser un ContextWrapperest qu'il vous permet de «modifier le comportement sans changer le contexte d'origine». Par exemple, si vous avez une activité appelée, vous myActivitypouvez en créer un Viewavec un thème différent de celui-ci myActivity:

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

ContextWrapperest vraiment puissant , car il vous permet de passer outre la plupart des fonctions fournies par Contexty compris le code d'accès aux ressources (par exemple openFileInput(), getString()), interagir avec d' autres composants (par exemple sendBroadcast(), registerReceiver()), les autorisations des demandes (par exemple checkCallingOrSelfPermission()) et la résolution des emplacements du système de fichiers (par exemple getFilesDir()). ContextWrapperest très utile pour contourner les problèmes spécifiques à l'appareil / à la version ou pour appliquer des personnalisations ponctuelles à des composants tels que des vues qui nécessitent un contexte.

La méthode getBaseContext () peut être utilisée pour accéder au contexte «de base» qui ContextWrapperentoure. Si vous avez besoin, par exemple, vérifier si elle est un que vous pourriez avoir besoin d'accéder au contexte « de base » Service, Activityou 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");
    }
    ...
  }
}

Ou si vous devez appeler la version «déballée» d'une méthode:

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}
Mike Laren
la source
17
Je dirais que c'est la réponse la plus importante après une acceptée.
0leg
4
Je dirais que l'existence de ContextWrapperest l'une des pires décisions jamais prises par les développeurs de framework Android. Quand ils ont réalisé qu'ils avaient créé une famille entière d'objets divins, au lieu de faire la bonne chose et de refactoriser le code vers la responsabilité unique, ils ont ajouté un hack laid qui a permis de changer le comportement du contexte en approfondissant l'arbre d'héritage. Mauvaise ingénierie logicielle à son plus laid. Quant à nous, développeurs, à mon humble avis, personne ne devrait jamais utiliser getBaseContext()ou ContextWrapper. Si vous le faites, c'est une énorme "odeur de code".
Vasiliy
Je voudrais voir le CustomToastcode complet . THANKS :)))
Alston
39

getApplicationContext () - Renvoie le contexte de toutes les activités en cours d'exécution dans l'application.

getBaseContext () - Si vous souhaitez accéder au contexte à partir d'un autre contexte dans l'application, vous pouvez y accéder.

getContext () - Renvoie la vue contextuelle uniquement l'activité en cours d'exécution.

Jay Patel
la source
1
Les pls intègrent les lettres A et B dans votre définition du contexte dans le contexte, il n'est pas clair dans aucune réponse quel contexte est consulté.
Espérons que le
30

La question «quel est le contexte» est l'une des questions les plus difficiles de l'univers Android.

Le contexte définit des méthodes qui accèdent aux ressources système, récupèrent les actifs statiques de l'application, vérifient les autorisations, effectuent des manipulations d'interface utilisateur et bien d'autres. Essentiellement, Contextest un exemple d'anti-modèle de Dieu Objet en production.

Quand il s'agit de savoir quel type d' Contextutilisation devons-nous utiliser, cela devient très compliqué car, à l'exception d'être Dieu Objet, l'arborescence hiérarchique des Contextsous - classes viole brutalement le principe de substitution de Liskov.

Ce billet de blog tente de résumer l' Contextapplicabilité des classes dans différentes situations.

Permettez-moi de copier le tableau principal de ce message pour être complet:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | 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. Une application PEUT démarrer une activité à partir d'ici, mais elle nécessite qu'une nouvelle tâche soit créée. Cela peut correspondre à des cas d'utilisation spécifiques, mais peut créer des comportements de pile arrière non standard dans votre application et n'est généralement pas recommandé ou considéré comme une bonne pratique.
  2. C'est légal, mais l'inflation se fera avec le thème par défaut pour le système sur lequel vous exécutez, pas ce qui est défini dans votre application.
  3. Autorisé si le récepteur est nul, ce qui est utilisé pour obtenir la valeur actuelle d'une diffusion persistante, sur Android 4.2 et supérieur.

capture d'écran

Vasiliy
la source
Excellent article de blog auquel vous avez lié!
lejonl
28

Contextfournit des informations sur le ActvityouApplication sur les composants nouvellement créés.

Des informations pertinentes Contextdoivent être fournies pour les composants nouvellement créés (que ce soit le contexte d'application ou le contexte d'activité)

Étant donné qu'il Activitys'agit d'une sous-classe de Context, on peut utiliser thispour obtenir le contexte de cette activité

tez
la source
Où est votre explication sur baseContext?
IgorGanapolsky
1

De cette documentation

J'ai compris que vous devez utiliser:

Essayez d'utiliser l'application contextuelle au lieu d'une activité contextuelle

mehmet
la source
1

getApplicationContext ()

il est utilisé pour le niveau d'application et fait référence à toutes les activités.

getContext () et getBaseContext ()

est très probablement le même. Ceux-ci ne sont référés qu'à l'activité en cours qui est en direct.

cette

est toujours référence à l'objet de classe actuel.

Jatin Bansal
la source
0

A Contextest:

  • une classe abstraite dont l'implémentation est fournie par le système Android.
  • Il permet d'accéder à des ressources et des classes spécifiques à l'application, ainsi qu'à des appels ascendants pour des opérations au niveau de l'application telles que le lancement d'activités, la diffusion et la réception d'intentions, etc.
SANKET RAMANI
la source