252

这让我很难过,我在 Android 2.1-r8 SDK 中使用它:

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

并且也在

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

使用getApplicationContext()崩溃ProgressDialogToast....这导致我这个问题:

尽管共享“上下文”一词,但活动上下文和应用程序上下文之间的实际区别是什么?

4

7 回答 7

276

它们都是Context的实例,但应用程序实例与应用程序的生命周期相关联,而 Activity 实例与 Activity 的生命周期相关联。因此,他们可以访问有关应用程序环境的不同信息。

如果您阅读getApplicationContext上的文档,它会指出,如果您需要一个生命周期与当前上下文分开的上下文,您应该只使用它。这不适用于您的任何一个示例。

Activity 上下文大概有一些关于当前活动的信息,这些信息是完成这些调用所必需的。如果您显示确切的错误消息,则可能能够指出它到底需要什么。

但总的来说,除非您有充分的理由不这样做,否则请使用活动上下文。

于 2010-11-08T22:33:52.667 回答
210

我发现这张表对于决定何时使用不同类型的上下文非常有用:

在此处输入图像描述

  1. 应用程序可以从这里启动一个 Activity,但它需要创建一个新任务。这可能适合特定的用例,但可能会在您的应用程序中创建非标准的回栈行为,通常不推荐或不被认为是好的做法。
  2. 这是合法的,但膨胀将使用您正在运行的系统的默认主题完成,而不是您的应用程序中定义的主题。
  3. 如果接收者为 null 则允许,用于获取粘性广播的当前值,在 Android 4.2 及更高版本上。

原创文章在这里

于 2016-02-03T23:17:36.177 回答
37

这显然是 API 设计的缺陷。首先,Activity Context和Application context是完全不同的对象,所以使用context的方法参数应该使用ApplicationContextorActivity直接,而不是使用父类Context。其次,文档应该明确指定使用或不使用哪个上下文。

于 2014-06-30T09:52:52.397 回答
17

我认为的原因ProgressDialog是附加到支持的活动,ProgressDialog因为对话框在活动被破坏后无法保留,因此它需要传递this(ActivityContext),它也会随着活动而被破坏,而 ApplicationContext 即使在活动被破坏后仍然存在被摧毁。

于 2014-07-25T10:59:18.193 回答
3

我认为当一切都需要屏幕来显示(按钮、对话框、布局......)时,我们必须使用上下文活动,而一切都不需要屏幕来显示或处理(吐司、服务电话、联系人......)我们可以使用应用程序上下文

于 2015-05-04T06:03:44.893 回答
3

如果您需要与本身将具有全局范围的上下文相关联的东西,请使用 getApplicationContext() 。

如果你使用Activity,那么新的Activity实例会有一个引用,它对旧的Activity有一个隐式的引用,旧的Activity不能被垃圾回收。

于 2016-03-04T05:59:44.477 回答
3

当您直接从主屏幕启动应用程序与通过共享意图从另一个应用程序启动应用程序时,您可以看到这两种上下文之间的差异。

这是@CommonSenseCode提到的“非标准回栈行为”的实际示例:

假设您有两个相互通信的应用程序App1App2

从启动器启动App2:MainActivity。然后从 MainActivity 启动App2:SecondaryActivity。在那里,无论是使用活动上下文还是应用程序上下文,两个活动都存在于同一个任务中,这是可以的(假设您使用所有标准启动模式和意图标志)。您可以通过后按返回 MainActivity,而在最近的应用程序中,您只有一项任务。

现在假设您在App1中并以共享意图(ACTION_SEND 或 ACTION_SEND_MULTIPLE)启动App2:MainActivity 。然后从那里尝试启动App2:SecondaryActivity(始终使用所有标准启动模式和意图标志)。会发生什么:

  • 如果您在 Android < 10 上使用应用程序上下文启动 App2:SecondaryActivity ,则无法在同一任务中启动所有活动。我已经尝试过使用 android 7 和 8,并且 SecondaryActivity 总是在新任务中启动(我猜是因为 App2:SecondaryActivity 是使用 App2 应用程序上下文启动的,但是您来自 App1 并且您没有直接启动 App2 应用程序.也许在引擎盖下android识别并使用FLAG_ACTIVITY_NEW_TASK)。根据您的需要,这可能是好是坏,因为我的应用程序很糟糕。
    在 Android 10 上,应用程序崩溃并显示消息
    “从 Activity 上下文外部调用 startActivity() 需要 FLAG_ACTIVITY_NEW_TASK 标志。这真的是你想要的吗?” .
    因此,要使其在 Android 10 上运行,您必须使用 FALG_ACTIVITY_NEW_TASK 并且不能在同一任务中运行所有活动。
    如您所见,android 版本之间的行为不同,很奇怪。

  • 如果您使用活动上下文启动 App2:SecondaryActivity 一切顺利,您可以在同一任务中运行所有活动,从而实现线性回栈导航。

我希望我添加了一些有用的信息

于 2019-11-14T12:37:51.347 回答