活动上下文和应用程序上下文之间的区别


233

这让我感到困惑,我在Android 2.1-r8 SDK中使用了它:

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

并且在

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

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

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



14
这应该有助于清除一些内容:上下文,什么上下文?
toobsco42 2013年

Answers:


250

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

如果您在getApplicationContext上阅读文档,它会指出,只有在需要其生命周期与当前上下文分开的上下文时,才应使用此文档。这在您的两个示例中均不适用。

活动上下文大概具有有关当前活动的一些信息,这些信息对于完成这些调用是必需的。如果显示确切的错误消息,则可能能够指出确切的需求。

但通常,除非有充分理由不使用活动上下文,否则请使用它。


1
getApplicationContext有趣的是,使用时我得到了一个“ java.lang.reflect.InvocationTargetException” ,当我更改为时this,它没有崩溃并无法按预期工作....因此,如果它们都是Context实例,为什么一个都不起作用并且其他呢?我希望此信息会对其他人有所帮助... :)感谢您的迅速回答...
t0mm13b 2010年

2
我需要查看完整的异常stacktrace才能说什么。但是,正如我所说的,上下文实例具有不同的信息。大概是要在屏幕上显示对话框或吐司,需要有关仅Activity实例具有的Activity的信息。
谢丽尔·西蒙

74
我想说的是使用应用程序上下文,除非您没有充分的理由(例如对话或敬酒)。在不同情况下使用活动上下文很容易遇到内存泄漏,因此最好保证安全:) android-developers.blogspot.com/2009/01/…–
Dori

10
Dave Smith发布了一个非常好的博客文章,以了解上下文的用法,请参见此处。确保您还阅读了评论!
ChrLipp

1
事实是,甚至Dianna Hackborn都建议使用活动上下文。stackoverflow.com/questions/5228160/…但是她似乎对此不太确定。
JacksOnF1re 2015年

178

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

在此处输入图片说明

  1. 应用程序可以从此处启动活动,但是它需要创建一个新任务。这可能适合特定的用例,但可能会在您的应用程序中创建非标准的Back Stack行为,通常不建议这样做,也不认为这是一种好的做法。
  2. 这是合法的,但是通货膨胀将使用您正在运行的系统的默认主题来完成,而不是应用程序中定义的主题。
  3. 在Android 4.2及更高版本上,如果接收器为null(用于获取即时广播的当前值),则允许使用。

原始文章在这里



如何获得资源呢?我认为您最好将其添加到表中。您可以使用应用上下文访问资源。
阿米尔·齐亚拉蒂

我们可以从应用程序上下文开始活动
Duy Phan

文章也可以在这里找到:wundermanthompsonmobile.com/2013/06/context
静物

34

这显然是API设计的缺陷。首先,活动上下文和应用程序上下文是完全不同的对象,因此使用上下文的方法参数应该使用ApplicationContextActivity直接使用,而不是使用父类Context。其次,文档应指定要使用或不明确使用的上下文。


25
完全同意。Google对此一掷千金。这是一团糟。
索伦Boisen

@SørenBoisenAndroid SDK中是一塌糊涂
CommonSenseCode

他们知道混乱的局面,并确信他们正在竭尽全力解决问题。
签名

15

我认为这ProgressDialogProgressDialog因为活动被破坏后对话框无法保留,所以它与活动的支撑有关,因此需要通过this活动传递它(ActivityContext),活动也会被销毁,而ApplicationContext甚至在活动获得后仍然保留毁了。


3

如果您需要与本身具有全局范围的Context相关联的内容,请使用getApplicationContext()。

如果使用Activity,则新的Activity实例将具有一个引用,该引用具有对旧Activity的隐式引用,并且不能对旧的Activity进行垃圾回收。


2

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


1

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

在这里,@ CommonSenseCode提到的“非标准后退堆栈行为”的实际示例表示:

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

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

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

  • 如果您在Android <10上使用应用程序上下文启动App2:SecondaryActivity,则无法同一任务中启动所有活动。我尝试使用android 7和android 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,则一切运行良好,并且您可以在同一任务中运行所有活动,从而实现线性后退导航。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.