Je n'ai pas pu trouver de réponse satisfaisante à cela, alors allons-y: quel est le problème Activity/Service.getApplication()
et Context.getApplicationContext()
?
Dans notre application, les deux retournent le même objet. Dans un cas ActivityTestCase
cependant, se moquer de l'application fera getApplication()
revenir avec la maquette, mais getApplicationContext
retournera toujours une instance de contexte différente (une injectée par Android). Est-ce un bug? Est-ce exprès?
Je ne comprends même pas la différence en premier lieu. Existe-t-il des cas en dehors d'une suite de tests où les deux appels peuvent revenir avec des objets différents? Quand et pourquoi? De plus, pourquoi est getApplication
défini sur Activity
et Service
, mais pas sur Context
? Ne devrait-il pas toujours y avoir une instance d'application valide disponible de n'importe où ?
Application
objet dans votre application.Réponses:
Question très intéressante. Je pense que c'est principalement un sens sémantique, et peut également être dû à des raisons historiques.
Bien que dans les implémentations actuelles d'Activité et de Service Android,
getApplication()
etgetApplicationContext()
renvoyant le même objet, il n'y a aucune garantie que ce sera toujours le cas (par exemple, dans une implémentation de fournisseur spécifique).Donc, si vous voulez la classe Application que vous avez enregistrée dans le manifeste, vous ne devez jamais l' appeler
getApplicationContext()
et la transtyper dans votre application, car il ne s'agit peut-être pas de l'instance d'application (que vous avez manifestement expérimentée avec le framework de test).Pourquoi
getApplicationContext()
existe- t- il en premier lieu?getApplication()
est uniquement disponible dans la classe Activity et la classe Service, alors qu'ilgetApplicationContext()
est déclaré dans la classe Context.Cela signifie en fait une chose: lorsque vous écrivez du code dans un récepteur de diffusion, qui n'est pas un contexte mais reçoit un contexte dans sa méthode onReceive, vous ne pouvez qu'appeler
getApplicationContext()
. Ce qui signifie également que vous n'êtes pas assuré d'avoir accès à votre application dans un BroadcastReceiver.Lorsque vous regardez le code Android, vous voyez que lorsqu'elle est attachée, une activité reçoit un contexte de base et une application, et ce sont des paramètres différents.
getApplicationContext()
délègue son appelbaseContext.getApplicationContext()
.Une dernière chose: la documentation indique que dans la plupart des cas, vous ne devriez pas avoir besoin de sous-classer Application:
Je sais que ce n'est pas une réponse exacte et précise, mais est-ce que cela répond à votre question?
la source
android.app.Application
- classement est super complet. Par exemple, j'ai eu des problèmes sans fin lors de l'initialisation de la base de données. Une fois emménagé,Application.onCreate
il fonctionnait comme un charme. Maintenant, je fais toute l'initialisation à l'échelle du systèmeApplication
et je n'écrirais pas une autre application sans.Comparez
getApplication()
etgetApplicationContext()
.getApplication
renvoie unApplication
objet qui vous permettra de gérer l'état de votre application globale et de répondre à certaines situations de périphérique telles queonLowMemory()
etonConfigurationChanged()
.getApplicationContext
renvoie le contexte d'application global - la différence par rapport aux autres contextes est que, par exemple, un contexte d'activité peut être détruit (ou autrement rendu indisponible) par Android lorsque votre activité se termine. Le contexte d'application reste disponible pendant que votre objet Application existe (qui n'est pas lié à un spécifiqueActivity
), vous pouvez donc l'utiliser pour des choses comme les notifications qui nécessitent un contexte qui sera disponible pendant de plus longues périodes et indépendant des objets d'interface utilisateur transitoires.Je suppose que cela dépend de ce que fait votre code, que ceux-ci soient identiques ou non - bien qu'en utilisation normale, je m'attends à ce qu'ils soient différents.
la source
Application
est unContext
(il en hérite), et au moment de l'exécution, les deux méthodes retournent la même instance. Alors quelle est la différence?Activity
contexte et unApplication
contexte. Je réfléchis à la différence entreApplication
(qui est le contexte d'application global et unique) et tout ce quigetApplicationContext
revient. Ce dernier n'était en fait pas fonctionnel avant Android 1.6; il revenait toujoursnull
.Cela semble avoir à voir avec l'habillage du contexte. La plupart des classes dérivées de
Context
sont en fait unContextWrapper
, qui délègue essentiellement à un autre contexte, éventuellement avec des modifications par le wrapper.Le contexte est une abstraction générale qui prend en charge la simulation et le proxy. Étant donné que de nombreux contextes sont liés à un objet à durée de vie limitée tel qu'un
Activity
, il doit y avoir un moyen d'obtenir un contexte de plus longue durée, à des fins telles que l'inscription à de futures notifications. Cela est réalisé parContext.getApplicationContext()
. Une implémentation logique consiste à renvoyer l'Application
objet global , mais rien n'empêche une implémentation de contexte de renvoyer à la place un wrapper ou un proxy avec une durée de vie appropriée.Les activités et services sont plus spécifiquement associés à un
Application
objet. L'utilité de cela, je crois, est que vous pouvez créer et enregistrer dans le manifeste une classe personnalisée dérivée deApplication
et être certain queActivity.getApplication()
ouService.getApplication()
retournera cet objet spécifique de ce type spécifique, que vous pouvez convertir dans votreApplication
classe dérivée et utiliser pour tout but personnalisé.En d'autres termes, il
getApplication()
est garanti de renvoyer unApplication
objet, tandis qu'ilgetApplicationContext()
est libre de renvoyer un proxy à la place.la source
Pour répondre à la question, getApplication () renvoie un objet Application et getApplicationContext () renvoie un objet Context. Sur la base de vos propres observations, je suppose que le contexte des deux est identique (c'est-à-dire que dans les coulisses, la classe Application appelle cette dernière fonction pour remplir la partie Contexte de la classe de base ou qu'une action équivalente a lieu). Peu importe la fonction que vous appelez, si vous avez juste besoin d'un contexte.
la source