Différence entre le contexte d'activité et le contexte d'application

233

Cela m'a dérouté, j'utilisais cela dans le SDK Android 2.1-r8:

ProgressDialog.show(getApplicationContext(), ....);

et aussi

Toast t = Toast.makeText(getApplicationContext(),....);

en utilisant les getApplicationContext()plantages à la fois ProgressDialoget Toast.... ce qui m'amène à cette question:

Quelles sont les différences réelles entre un contexte d'activité et un contexte d'application, malgré le partage du libellé «Contexte»?

t0mm13b
la source
C'est ce que j'ai trouvé stackoverflow.com/questions/1561803/… ....
t0mm13b
14
Cela devrait aider à clarifier certaines choses: Contexte, quel contexte?
toobsco42

Réponses:

250

Ce sont deux instances de contexte , mais l'instance d'application est liée au cycle de vie de l'application, tandis que l'instance d'activité est liée au cycle de vie d'une activité. Ainsi, ils ont accès à différentes informations sur l'environnement d'application.

Si vous lisez les documents sur getApplicationContext, il note que vous ne devez l'utiliser que si vous avez besoin d'un contexte dont le cycle de vie est distinct du contexte actuel. Cela ne s'applique à aucun de vos exemples.

Le contexte d'activité contient probablement des informations sur l'activité en cours qui sont nécessaires pour terminer ces appels. Si vous affichez le message d'erreur exact, vous pourrez peut-être indiquer exactement ce dont il a besoin.

Mais en général, utilisez le contexte d'activité sauf si vous avez une bonne raison de ne pas le faire.

Cheryl Simon
la source
1
J'ai eu une 'java.lang.reflect.InvocationTargetException' lors de l'utilisation getApplicationContext, assez intéressant, quand j'ai changé pour this, il n'a pas planté et n'a pas fonctionné comme prévu .... donc si ce sont deux instances de Context, pourquoi ne fonctionne-t-il pas et l'autre le fait? Cette information sera utile aux autres, j'espère ... :) merci pour votre réponse rapide ...
t0mm13b
2
J'aurais besoin de voir la trace de pile d'exceptions complète pour pouvoir dire quoi que ce soit. Cependant, comme je l'ai dit, les instances de contexte ont des informations différentes. Vraisemblablement pour afficher une boîte de dialogue ou un toast à l'écran, il faut des informations sur l'activité que seule l'instance d'activité possède.
Cheryl Simon
74
Je dirais utiliser le contexte de l'application à moins que vous n'ayez pas de bonnes raisons (par exemple pour les dialogues ou les toasts). Il est assez facile de rencontrer des fuites de mémoire en utilisant des contextes d'activité dans différentes situations, il vaut
Dori
10
Dave Smith a publié une très bonne entrée de blog pour comprendre l'utilisation du contexte, voir ici . Assurez-vous de lire également les commentaires!
ChrLipp
1
Le fait est que même Dianna Hackborn recommande d'utiliser le contexte d'activité. stackoverflow.com/questions/5228160/… Mais elle ne semble pas en être totalement sûre.
JacksOnF1re
178

J'ai trouvé ce tableau super utile pour décider quand utiliser différents types de contextes:

entrez la description de l'image ici

  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.

Article original ici .

CommonSenseCode
la source
qu'en est-il d'obtenir les ressources? je pense que vous feriez mieux de l'ajouter à votre table. et vous pouvez accéder aux ressources avec un contexte d'applciation.
Amir Ziarati
Nous pouvons commencer l'activité à partir du contexte de l'application
Duy Phan
L'article peut également être trouvé ici: wundermanthompsonmobile.com/2013/06/context
Lifes
34

C'est évidemment une lacune de la conception de l'API. En premier lieu, le contexte d'activité et le contexte d'application sont des objets totalement différents, de sorte que les paramètres de méthode dans lesquels le contexte est utilisé doivent utiliser ApplicationContextou Activitydirectement, au lieu d'utiliser la classe parent Context. En second lieu, le doc doit spécifier quel contexte utiliser ou non explicitement.

lucas
la source
25
Entièrement d'accord. Google a laissé tomber le ballon sur celui-ci. C'est un gâchis complet.
Søren Boisen
@ SørenBoisen android sdk est un gâchis complet
CommonSenseCode
Ils sont conscients du désordre et sont sûrs qu'ils ont du mal à réparer autant qu'ils le peuvent.
pasignature
15

La raison pour laquelle je pense que ProgressDialogc'est attaché à l'activité qui soutient le ProgressDialogcar la boîte de dialogue ne peut pas rester après que l'activité soit détruite donc elle doit être passée this(ActivityContext) qui est également détruite avec l'activité alors que le ApplicationContext reste même après que l'activité soit détruit.

user2779311
la source
3

Utilisez getApplicationContext () si vous avez besoin de quelque chose lié à un contexte qui lui-même aura une portée globale.

Si vous utilisez Activity, la nouvelle instance Activity aura une référence, qui a une référence implicite à l'ancienne Activity, et l'ancienne Activity ne peut pas être récupérée.

Dhiraj Himani
la source
2

Je pense que lorsque tout a besoin d'un écran pour s'afficher (bouton, dialogue, mise en page ...) nous devons utiliser une activité contextuelle, et tout n'a pas besoin d'un écran pour afficher ou traiter (toast, service telelphone, contact ...) nous pourrait utiliser un contexte d'application

Dmobile
la source
1

Vous pouvez voir une différence entre les deux contextes lorsque vous lancez votre application directement depuis l'écran d'accueil et lorsque votre application est lancée à partir d'une autre application via l'intention de partage.

Voici un exemple pratique de ce que "les comportements de pile arrière non standard", mentionnés par @CommonSenseCode, signifie:

Supposons que vous ayez deux applications qui communiquent entre elles, App1 et App2 .

Lancez App2: MainActivity à partir du lanceur. Puis à partir de MainActivity, lancez App2: SecondaryActivity . Là, en utilisant le contexte d'activité ou le contexte d'application, les deux activités vivent dans la même tâche et c'est ok (étant donné que vous utilisez tous les modes de lancement standard et les indicateurs d'intention). Vous pouvez revenir à MainActivity avec une presse arrière et dans les applications récentes, vous n'avez qu'une seule tâche.

Supposons maintenant que vous êtes dans App1 et lancez App2: MainActivity avec une intention de partage (ACTION_SEND ou ACTION_SEND_MULTIPLE). Ensuite, essayez de lancer App2: SecondaryActivity (toujours avec tous les modes de lancement standard et les indicateurs d'intention). Ce qui se produit est:

  • si vous lancez App2: SecondaryActivity avec le contexte d'application sur Android <10, vous ne pouvez pas lancer toutes les activités dans la même tâche . J'ai essayé avec Android 7 et 8 et le SecondaryActivity est toujours lancé dans une nouvelle tâche (je suppose que c'est parce que App2: SecondaryActivity est lancé avec le contexte de l'application App2 mais vous venez d'App1 et vous n'avez pas lancé l'application App2 directement Peut-être que sous le capot, android reconnaît cela et utilise FLAG_ACTIVITY_NEW_TASK). Cela peut être bon ou mauvais selon vos besoins, car ma candidature était mauvaise.
    Sur Android 10, l' application se bloque avec le message
    "L'appel de startActivity () à l'extérieur d'un contexte d'activité nécessite l'indicateur FLAG_ACTIVITY_NEW_TASK. Est-ce vraiment ce que vous voulez?" .
    Donc, pour le faire fonctionner sur Android 10, vous devez utiliser FALG_ACTIVITY_NEW_TASK et vous ne pouvez pas exécuter toutes les activités dans la même tâche.
    Comme vous pouvez le voir, le comportement est différent entre les versions Android, bizarre.

  • si vous lancez App2: SecondaryActivity avec le contexte d'activité, tout se passe bien et vous pouvez exécuter toutes les activités dans la même tâche, ce qui entraîne une navigation linéaire en backstack.

J'espère avoir ajouté quelques informations utiles

DSoldo
la source