getApplication()与getApplicationContext()

我无法找到一个令人满意的答案,所以在这里我们去: Activity/Service.getApplication()Context.getApplicationContext()什么?

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

我甚至不了解其中的差别。 在测试套件之外,是否有两个调用可能返回不同的对象? 何时,为什么? 而且,为什么getApplicationActivityService上定义,而不是在Context ? 不应该总是有从任何地方有效的应用程序实例吗?

非常有趣的问题。 我认为这主要是一个语义,也可能是由于历史的原因。

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

所以如果你想要在Manifest中注册的Application类,你不应该调用getApplicationContext()并把它转换到你的应用程序,因为它可能不是应用程序实例(你明显体验到了测试框架)。

为什么getApplicationContext()首先存在?

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

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

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

还有一件事:文档说,大多数情况下,你不应该需要子类Application:

通常不需要子类Application 。 在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。 如果你的单例需要一个全局上下文(例如注册广播接收者),那么检索它的函数可以被赋予一个Context ,它在第一次构造单例时在内部使用Context.getApplicationContext()

我知道这不是确切而确切的答案,但是,这是否回答你的问题?

比较getApplication()getApplicationContext()

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

getApplicationContext返回全局应用程序上下文 – 与其他上下文的不同之处在于,例如,当您的活动结束时,活动上下文可能会被Android销毁(或以其他方式不可用)。 应用程序上下文在你的应用程序对象存在的时候一直保持可用(不绑定到特定的Activity ),所以你可以使用它来处理像通知这样的事情,这需要一个上下文,这个上下文将可用于更长的时间,并且独立于临时UI对象。

我想这取决于你的代码在做什么,不管它们是否可以相同 – 虽然在正常使用中,我希望它们是不同的。

这似乎与上下文包装有关。 从Context派生的大多数类实际上是一个ContextWrapper ,实质上委托给另一个上下文,可能与包装的变化。

上下文是支持嘲笑和代理的一般抽象。 由于许多上下文都绑定到一个有限生命周期的对象(如Activity ,因此需要有一种方法来获得更长寿命的上下文,以用于注册将来的通知等用途。 这是通过Context.getApplicationContext()来实现的。 逻辑实现是返回全局Application对象,但是没有任何东西阻止上下文实现返回具有合适的生命周期的包装或代理。

活动和服务更具体地与一个Application对象相关联。 我相信这一点的用处在于,您可以在清单中创建并注册从Application导出的自定义类,并确保Activity.getApplication()Service.getApplication()将返回该特定类型的特定对象,你可以投到你的派生Application类和用于任何自定义的目的。

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

为了回答这个问题,getApplication()返回一个Application对象,getApplicationContext()返回一个Context对象。 基于你自己的观察,我会假设两者的Context都是相同的(例如Application类调用后一个函数来填充基类的Context部分或发生一些等效的动作)。 如果您只需要一个上下文,那么调用哪个函数应该无关紧要。