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. S'il vous plaît donner des exemples faciles si possible.
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 pour l'application entière (le processus dans lequel toutes les activités sont exécutées). 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é actuelle.
ContextWrapper.getBaseContext()
: Si vous avez besoin d'accéder à un contexte à partir d'un autre contexte, vous utilisez un ContextWrapper. Le contexte référencé depuis l'intérieur de ContextWrapper est accessible via getBaseContext ().
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 avez un ContextWrapper
name__. Android fournit une classe ContextWrapper
qui est créée autour d'un Context
existant à l'aide de:
ContextWrapper wrapper = new ContextWrapper(context);
L’utilisation d’un ContextWrapper
permet de "modifier le comportement sans modifier le contexte d’origine". Par exemple, si vous avez une activité appelée myActivity
name__, vous pouvez créer un View
avec un thème différent de myActivity
name__:
ContextWrapper customTheme = new ContextWrapper(myActivity) {
@Override
public Resources.Theme getTheme() {
return someTheme;
}
}
View myView = new MyView(customTheme);
ContextWrapper
est vraiment puissant car il vous permet de remplacer la plupart des fonctions fournies par Context
name__, y compris le code permettant d'accéder aux ressources (par exemple, openFileInput()
, getString()
), d'interagir avec d'autres composants (par exemple, sendBroadcast()
, registerReceiver()
) et de demander des autorisations (par exemple, checkCallingOrSelfPermission()
). getFilesDir()
). ContextWrapper
est vraiment utile pour résoudre des problèmes spécifiques à un périphérique/une version ou pour appliquer des personnalisations uniques aux composants tels que les vues nécessitant un contexte.
La méthode getBaseContext () peut être utilisée pour accéder au contexte "de base" que le ContextWrapper
encercle. Vous devrez peut-être accéder au contexte "de base" si vous devez, par exemple, vérifier s'il s'agit d'un Service
name____, Activity
ou Application
name__:
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 avez besoin d'appeler la version "non emballée" d'une méthode:
class MyCustomWrapper extends ContextWrapper {
@Override
public Drawable getWallpaper() {
if (BuildInfo.DEBUG) {
return mDebugBackground;
} else {
return getBaseContext().getWallpaper();
}
}
}
getApplicationContext () - Retourne le contexte pour 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 de l'application, vous pouvez y accéder.
getContext () - Renvoie la vue contextuelle uniquement l'activité en cours.
Context
fournit des informations sur Actvity
ou Application
aux composants nouvellement créés.
Context
doit être fourni aux composants nouvellement créés (que ce soit le contexte d'application ou le contexte d'activité)
Activity
étant une sous-classe de Context
name__, on peut utiliser this
pour obtenir le contexte de cette activité.
La question "quel est le contexte" est l’une des questions les plus difficiles de l’univers Android.
Le contexte définit les 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, etc. Context
est un exemple d'anti-motif de Dieu Object en production.
Quand il s'agit de quel type de Context
devrions-nous utiliser, cela devient très compliqué car, sauf qu'être un objet divin, l'arbre de la hiérarchie des sous-classes Context
viole brutalement le principe de substitution de Liskov.
Cet article de blog tente de résumer l'applicabilité des classes Context
dans différentes situations.
Permettez-moi de copier la table principale de cet article pour compléter:
+----------------------------+-------------+----------+---------+-----------------+-------------------+ | | 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 | +----------------------------+-------------+----------+---------+-----------------+-------------------+
- Une application PEUT démarrer une activité à partir d'ici, mais cela nécessite la création d'une nouvelle tâche. Cela peut convenir à des cas d'utilisation spécifiques, mais peut créer des comportements de pile de retour non standard dans votre application et n'est généralement pas recommandé ni considéré comme une bonne pratique.
- C’est légal, mais l’inflation se fera avec le thème par défaut du système sur lequel vous exécutez, et non selon ce qui est défini dans votre application.
- Autorisé si le récepteur est nul, utilisé pour obtenir la valeur actuelle d'une diffusion persistante sur Android 4.2 et versions ultérieures.
A partir de ceci docs
J'ai compris que vous devriez utiliser:
Essayez d'utiliser l'application de contexte au lieu d'une activité de contexte.
getApplicationContext ()
ceci est utilisé pour le niveau d'application et se réfère à toutes les activités.
getContext () et getBaseContext ()
c’est probablement la même chose. Celles-ci ne concernent que l’activité en cours.
ceci
fait toujours référence à un objet de classe en cours.