我找不到令人满意的答案,所以我们走了:Activity/Service.getApplication()
和Context.getApplicationContext()
的交易是什么?
在我们的应用程序中,两者都返回相同的对象。但是在ActivityTestCase
中,模拟应用程序会使getApplication()
返回模拟,但getApplicationContext
仍将返回不同的上下文实例(由Android注入的实例)。那是一个错误吗?是故意的吗?
我甚至不了解差异。测试套件外是否存在两个呼叫可能带有不同对象的情况?何时以及为何?此外,为什么在getApplication
和Activity
上定义Service
,而在Context
上定义{{1}}?不应该总是有随处可用的有效应用程序实例吗?
答案 0 :(得分:352)
非常有趣的问题。我认为这主要是语义,也可能是由于历史原因。
虽然在当前的Android Activity和Service实现中,getApplication()
和getApplicationContext()
返回相同的对象,但无法保证始终如此(例如,在特定的供应商实现中)。
因此,如果你想要在Manifest中注册的Application类,你应该永远调用getApplicationContext()
并将其强制转换为你的应用程序,因为它可能不是应用程序实例(你是显然经验丰富的测试框架)。
为什么getApplicationContext()
首先存在?
getApplication()
仅在Activity类和Service类中可用,而getApplicationContext()
在Context类中声明。
这实际上意味着一件事:当在广播接收器中编写代码时,它不是上下文但在onReceive方法中给出了上下文,您只能调用getApplicationContext()
。这也意味着您无法保证能够在BroadcastReceiver中访问您的应用程序。
在查看Android代码时,您会看到在附加时,活动会收到基本上下文和应用程序,这些是不同的参数。 getApplicationContext()
委托baseContext.getApplicationContext()
致电。{/ p>
还有一件事:文档说大多数情况下,你不需要继承Application:
通常不需要继承
Application
。在大多数情况下, 静态单例可以在更模块化的情况下提供相同的功能 办法。如果您的单身人士需要全局上下文(例如注册 广播接收器),可以给出一个检索它的功能Context
在内部使用Context.getApplicationContext()
时 首先构建单身人士。
我知道这不是一个确切而准确的答案,但是,这仍然可以回答你的问题吗?
答案 1 :(得分:30)
比较getApplication()
和getApplicationContext()
。
getApplication
会返回一个Application
对象,可让您管理全局应用状态并回复某些设备情况,例如onLowMemory()
和onConfigurationChanged()
。
getApplicationContext
返回全局应用程序上下文 - 与其他上下文的区别在于,例如,当您的活动结束时,Android可能会销毁(或以其他方式使其不可用)活动上下文。应用程序上下文在您的Application对象存在时仍然可用(与特定的Activity
无关),因此您可以将此用于Notifications之类的需要更长时间可用的上下文的内容并且独立于瞬态UI对象。
我想这取决于你的代码在做什么,不管它们是否相同 - 尽管在正常使用中,我希望它们是不同的。
答案 2 :(得分:29)
这似乎与上下文包装有关。从Context
派生的大多数类实际上是ContextWrapper
,它基本上委托给另一个上下文,可能由包装器进行更改。
上下文是一种支持模拟和代理的通用抽象。由于许多上下文都绑定到有限生命周期的对象(例如Activity
),因此需要有一种方法来获取更长寿的上下文,例如注册将来的通知。这是通过Context.getApplicationContext()
实现的。逻辑实现是返回全局Application
对象,但没有什么能阻止上下文实现返回具有合适生命周期的包装器或代理。
活动和服务更具体地与Application
对象相关联。我相信,这有用的是,您可以在清单中创建并在Application
派生自定义类,并确保Activity.getApplication()
或Service.getApplication()
将返回该特定对象特定类型,您可以将其强制转换为派生的Application
类,并用于任何自定义目的。
换句话说,getApplication()
保证返回Application
个对象,而getApplicationContext()
则可以自由返回代理。
答案 3 :(得分:-13)
要回答这个问题,getApplication()返回一个Application对象,getApplicationContext()返回一个Context对象。基于您自己的观察,我假设两者的上下文是相同的(即幕后,Application类调用后一个函数来填充基类的Context部分或发生一些等效的操作)。如果你只需要一个Context,那么你调用哪个函数应该没关系。