这让我很难过,我在Android 2.1-r8 SDK中使用它:
ProgressDialog.show(getApplicationContext(), ....);
以及
Toast t = Toast.makeText(getApplicationContext(),....);
使用getApplicationContext()
崩溃了ProgressDialog
和Toast
....这引出了我的问题:
活动上下文和应用程序上下文之间的实际差异是什么,尽管分享了“上下文”的措辞?
答案 0 :(得分:226)
它们都是Context的实例,但应用程序实例与应用程序的生命周期相关联,而Activity实例与Activity的生命周期相关联。因此,他们可以访问有关应用程序环境的不同信息。
如果您阅读getApplicationContext处的文档,则会注意到,只有在需要生命周期与当前上下文不同的上下文时才应使用此文档。这不适用于您的任何一个示例。
活动上下文可能包含有关完成这些调用所需的当前活动的一些信息。如果您显示确切的错误消息,可能能够指出它究竟需要什么。
但一般来说,除非你有充分理由不使用活动上下文,否则请使用活动上下文。
答案 1 :(得分:143)
我发现这个表对于决定何时使用不同类型的上下文非常有用:
原创文章here。
答案 2 :(得分:27)
这显然是API设计的不足之处。首先,Activity Context和Application上下文是完全不同的对象,因此使用上下文的方法参数应直接使用ApplicationContext
或Activity
,而不是使用父类Context。
第二,doc应指定要使用或不使用的上下文。
答案 3 :(得分:11)
我认为原因是ProgressDialog
附加到支持ProgressDialog
的活动,因为在活动被销毁后对话框无法保留,因此需要传递this
( ActivityContext)也被活动破坏,而ApplicationContext甚至在活动被破坏后仍然存在。
答案 4 :(得分:1)
我认为当一切都需要一个屏幕显示(按钮,对话框,布局......)时,我们必须使用上下文活动,而且一切都不需要屏幕来显示或处理(烤面包,服务电话,联系.. 。)我们可以使用应用程序上下文
答案 5 :(得分:1)
直接从主屏幕启动应用程序与通过共享意图从另一个应用程序启动应用程序时,您会看到两种上下文之间的差异。
下面是@CommonSenseCode提到的“非标准后退堆栈行为”的实际示例:
假设您有两个相互通信的应用程序, App1 和 App2 。
从启动器中启动 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一切顺利,则可以在同一任务中运行所有活动,从而实现线性后退导航。
我希望我添加了一些有用的信息
答案 6 :(得分:0)
如果您需要绑定到本身具有全局范围的Context,请使用getApplicationContext()。
如果您使用Activity,那么新的Activity实例将有一个引用,该引用具有对旧Activity的隐式引用,并且旧的Activity不能被垃圾回收。