getApplication() 与 getApplicationContext()

发布于 2024-10-18 02:50:07 字数 523 浏览 6 评论 0 原文

我找不到令人满意的答案,所以我们开始:Activity/Service.getApplication()Context.getApplicationContext() 有何关系?

在我们的应用程序中,两者都返回相同的对象。然而,在 ActivityTestCase 中,模拟应用程序将使 getApplication() 返回模拟,但 getApplicationContext 仍将返回不同的上下文实例(由 Android 注入)。这是一个错误吗?是故意的吗?

我什至一开始就不明白其中的区别。在测试套件之外是否存在两个调用可能返回不同对象的情况?什么时候以及为什么?而且,为什么getApplication定义在ActivityService上,而不是定义在Context上?难道不应该总是有一个可以从任何地方获得的有效应用程序实例吗?

I couldn't find a satisfying answer to this, so here we go: what's the deal with Activity/Service.getApplication() and Context.getApplicationContext()?

In our application, both return the same object. In an ActivityTestCase however, mocking the application will make getApplication() come back with the mock, but getApplicationContext will still return a different context instance (one injected by Android). Is that a bug? Is it on purpose?

I don't even understand the difference in the first place. Are there cases outside a test suite where both calls may come back with different objects? When and why? Moreover, why is getApplication defined on Activity and Service, but not on Context? Shouldn't there always be a valid application instance available from anywhere?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

雪若未夕 2024-10-25 02:50:08

非常有趣的问题。我觉得主要是语义上的,也可能是历史原因造成的。

尽管在当前的 Android Activity 和 Service 实现中,getApplication()getApplicationContext() 返回相同的对象,但不能保证情况总是如此(例如,在特定供应商实现中)。

因此,如果您想要在清单中注册的 Application 类,您应该永远调用 getApplicationContext() 并将其转换为您的应用程序,因为它可能不是应用程序实例(您显然在测试框架中经历过)。

为什么 getApplicationContext() 存在?

getApplication() 仅在 Activity 类和 Service 类中可用,而 getApplicationContext() 在 Context 类中声明。

这实际上意味着一件事:在广播接收器中编写代码时,广播接收器不是上下文,但在其 onReceive 方法中给出了上下文,您只能调用 getApplicationContext() 。这也意味着不能保证您能够访问 BroadcastReceiver 中的应用程序。

查看 Android 代码时,您会发现附加时,活动会接收基本上下文和应用程序,而这些是不同的参数。 getApplicationContext() 将其调用委托给 baseContext.getApplicationContext()

另一件事:文档说,在大多数情况下,您不需要子类化应用程序:

通常不需要子类化Application。在大多数情况下,
静态单例可以以更加模块化的方式提供相同的功能
方式。如果您的单例需要全局上下文(例如注册
广播接收器),检索它的函数可以给出
Context 在内部使用 Context.getApplicationContext()
首先构建单例。

我知道这不是一个准确的答案,但这仍然可以回答您的问题吗?

Very interesting question. I think it's mainly a semantic meaning, and may also be due to historical reasons.

Although in current Android Activity and Service implementations, getApplication() and getApplicationContext() return the same object, there is no guarantee that this will always be the case (for example, in a specific vendor implementation).

So if you want the Application class you registered in the Manifest, you should never call getApplicationContext() and cast it to your application, because it may not be the application instance (which you obviously experienced with the test framework).

Why does getApplicationContext() exist in the first place ?

getApplication() is only available in the Activity class and the Service class, whereas getApplicationContext() is declared in the Context class.

That actually means one thing : when writing code in a broadcast receiver, which is not a context but is given a context in its onReceive method, you can only call getApplicationContext(). Which also means that you are not guaranteed to have access to your application in a BroadcastReceiver.

When looking at the Android code, you see that when attached, an activity receives a base context and an application, and those are different parameters. getApplicationContext() delegates it's call to baseContext.getApplicationContext().

One more thing : the documentation says that it most cases, you shouldn't need to subclass Application:

There is normally no need to subclass Application. In most situation,
static singletons can provide the same functionality in a more modular
way. If your singleton needs a global context (for example to register
broadcast receivers), the function to retrieve it can be given a
Context which internally uses Context.getApplicationContext() when
first constructing the singleton.

I know this is not an exact and precise answer, but still, does that answer your question?

挽你眉间 2024-10-25 02:50:08

这似乎与上下文包装有关。大多数从 Context 派生的类实际上是 ContextWrapper,它本质上委托给另一个上下文,可能会由包装器进行更改。

上下文是支持模拟和代理的通用抽象。由于许多上下文都绑定到有限生命周期的对象,例如 Activity,需要有一种方法来获得更长久的上下文,用于注册未来通知等目的。这是通过 Context.getApplicationContext()。逻辑实现是返回全局 Application 对象,但什么也没有防止上下文实现返回具有合适生命周期的包装器或代理。

活动和服务更具体地与 Application 对象相关联。我相信,这样做的用处在于,您可以在清单中创建并注册从 Application 派生的自定义类,并确保 Activity.getApplication()Service.getApplication() 将返回该特定类型的特定对象,您可以将其转换为派生的 < code>Application 类并用于任何自定义目的。

换句话说,getApplication() 保证返回一个 Application 对象,而 getApplicationContext() 则可以自由地返回一个代理。

It seems to have to do with context wrapping. Most classes derived from Context are actually a ContextWrapper, which essentially delegates to another context, possibly with changes by the wrapper.

The context is a general abstraction that supports mocking and proxying. Since many contexts are bound to a limited-lifetime object such as an Activity, there needs to be a way to get a longer-lived context, for purposes such as registering for future notifications. That is achieved by Context.getApplicationContext(). A logical implementation is to return the global Application object, but nothing prevents a context implementation from returning a wrapper or proxy with a suitable lifetime instead.

Activities and services are more specifically associated with an Application object. The usefulness of this, I believe, is that you can create and register in the manifest a custom class derived from Application and be certain that Activity.getApplication() or Service.getApplication() will return that specific object of that specific type, which you can cast to your derived Application class and use for whatever custom purpose.

In other words, getApplication() is guaranteed to return an Application object, while getApplicationContext() is free to return a proxy instead.

や三分注定 2024-10-25 02:50:08

比较 getApplication()getApplicationContext()

getApplication 返回一个 Application< /a> 对象,它允许您管理全局应用程序状态并响应某些设备情况,例如 onLowMemory()onConfigurationChanged()

getApplicationContext 返回全局应用程序上下文 - 与其他上下文的区别在于,例如,当您的 Activity 结束时,Android 可能会销毁 Activity 上下文(或以其他方式使其不可用)。当您的应用程序对象存在时,应用程序上下文始终可用(不绑定到特定的Activity),因此您可以将其用于通知,需要一个可长时间使用且独立于瞬态 UI 对象的上下文。

我想这取决于你的代码在做什么,这些是否相同 - 尽管在正常使用中,我希望它们是不同的。

Compare getApplication() and getApplicationContext().

getApplication returns an Application object which will allow you to manage your global application state and respond to some device situations such as onLowMemory() and onConfigurationChanged().

getApplicationContext returns the global application context - the difference from other contexts is that for example, an activity context may be destroyed (or otherwise made unavailable) by Android when your activity ends. The Application context remains available all the while your Application object exists (which is not tied to a specific Activity) so you can use this for things like Notifications that require a context that will be available for longer periods and independent of transient UI objects.

I guess it depends on what your code is doing whether these may or may not be the same - though in normal use, I'd expect them to be different.

温折酒 2024-10-25 02:50:08

为了回答这个问题,getApplication() 返回一个 Application 对象,而 getApplicationContext() 返回一个 Context 对象。根据您自己的观察,我假设两者的上下文是相同的(即在幕后,应用程序类调用后一个函数来填充基类的上下文部分或发生一些等效的操作)。如果您只需要一个上下文,那么调用哪个函数并不重要。

To answer the question, getApplication() returns an Application object and getApplicationContext() returns a Context object. Based on your own observations, I would assume that the Context of both are identical (i.e. behind the scenes the Application class calls the latter function to populate the Context portion of the base class or some equivalent action takes place). It shouldn't really matter which function you call if you just need a Context.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文