关于这两种情况是什么,已经有很多帖子了。但我还是不太明白

就我目前的理解而言: 每个都是其类的一个实例,这意味着一些程序员建议您尽可能经常使用this.getApplicationContext(),以免“泄漏”出任何内存。这是因为另一个This(获取Activity实例上下文)指向一个Activity,每当用户倾斜手机或离开应用程序时,Activity就会被销毁。显然垃圾收集器(GC)没有捕获,因此使用太多的内存..

但是谁能想出一些真正好的编码示例,在这些示例中使用this(获取当前Activity实例的上下文)是正确的,而应用程序上下文将是无用的/错误的?


当你使用活动上下文和应用程序上下文时,有两个很好的例子,当显示Toast消息或内置对话框消息时,使用应用程序上下文会导致异常:

ProgressDialog.show(this, ....);

or

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

这两者都需要来自活动上下文中的信息,而应用程序上下文中没有提供这些信息。


getApplicationContext()几乎总是错误的。Hackborn女士(在其他人中)已经非常明确地指出,只有当您知道为什么要使用getApplicationContext()时才使用getApplicationContext(),并且只有当您需要使用getApplicationContext()时才使用。

坦率地说,“一些程序员”使用getApplicationContext()(或getBaseContext(),在较小的程度上),因为他们的Java经验有限。它们实现了一个内部类(例如,活动中按钮的OnClickListener),并且需要一个Context。而不是使用MyActivity。为了获取外部类的this,他们使用getApplicationContext()或getBaseContext()来获取Context对象。

只有当您知道需要某个上下文的时候,才会使用getApplicationContext(),该上下文可能比您所拥有的任何其他可能存在的上下文都要长。场景包括:

Use getApplicationContext() if you need something tied to a Context that itself will have global scope. I use getApplicationContext(), for example, in WakefulIntentService, for the static WakeLock to be used for the service. Since that WakeLock is static, and I need a Context to get at PowerManager to create it, it is safest to use getApplicationContext(). Use getApplicationContext() when you bind to a Service from an Activity, if you wish to pass the ServiceConnection (i.e., the handle to the binding) between Activity instances via onRetainNonConfigurationInstance(). Android internally tracks bindings via these ServiceConnections and holds references to the Contexts that create the bindings. If you bind from the Activity, then the new Activity instance will have a reference to the ServiceConnection which has an implicit reference to the old Activity, and the old Activity cannot be garbage collected.

一些开发人员为他们自己的全局数据使用Application的自定义子类,他们通过getApplicationContext()检索这些数据。这当然是可能的。我更喜欢静态数据成员,如果没有其他原因,你只能有一个自定义应用程序对象。我使用自定义Application对象构建了一个应用程序,发现它很痛苦。哈克伯恩女士也同意这一观点。

以下是不使用getApplicationContext()的原因:

它不是一个完整的上下文,支持Activity所做的一切。您尝试使用此Context做的各种事情都将失败,主要与GUI有关。 如果getApplicationContext()的Context保留了调用所创建的一些东西,而没有清理,则会造成内存泄漏。对于一个Activity,如果它持有一些东西,一旦该Activity被垃圾收集,其他所有东西也会被清除。Application对象在您的进程的生命周期内保持不变。


I think there's a lot of stuff that is poorly documented on the SDK site, this is one of them. The claim I'm going to make is that it seems as though it's better to default to using an application context and only use an activity context when you really need to. The only place where I've ever seen that you need an activity context is for a progress dialog. SBERG412 claims that you have to use an activity context for a toast message, yet the Android docs clearly show an application context being used. I've always used application context for toasts because of this Google example. If it's wrong to do so, then Google dropped the ball here.

这里有更多的思考和回顾:

对于toast消息,谷歌开发指南使用应用程序上下文并显式地说's来使用它: 烤面包的通知

在Dev指南的对话框部分,您可以看到一个AlertDialog。生成器使用应用程序上下文,然后进度条使用活动上下文。谷歌不能解释这一点。 对话框

It seems like a good reason to use application context is when you want to handle configuration changes like an orientation change, and you want to retain objects which need a context like Views. If you look here: Run Time Changes There is a caution about using an activity context, which can create a leak. This can be avoided with an application context with the views that are to be retained (at least that's my understanding). In an app I'm writing, I intend to use an application context because I'm trying to hold over some views and other things on an orientation change, and I still want the activity to be destroy and recreated on orientation changes. Thus I have to use an app context to not cause a memory leak (see Avoiding memory Leaks). To me it seems there are plenty of good reasons to use the application context instead of an activity context, and to me it almost seems like you would use it more often than an activity context. That's what many Android books I've gone through seem to do, and that's what much of the Google examples I've seen do.

The Google documentation really makes it seem like using application context is perfectly fine in most cases, and in fact appears more often than using an activity context in their examples (at least the examples I've seen). If it's really such a problem to use application context, then Google really needs to place more emphasis on this. They need to make it clear, and they need to redo some of their examples. I wouldn't blame this entirely on inexperienced developers since the authority (Google) really makes it look like it's not a problem to use application contexts.


应用程序上下文一直活到你的应用程序是活的,它不依赖于活动生命周期,但上下文保持对象是长生命的。如果你临时使用的对象是应用程序上下文和活动上下文,则使用完全相反的应用程序上下文。


使用哪个上下文?

有两种类型的上下文:

Application context is associated with the application and will always be same throughout the life of application -- it does not change. So if you are using Toast, you can use application context or even activity context (both) because toast can be displayed from anywhere with in your application and is not attached to a specific window. But there are many exceptions, one exception is when you need to use or pass the activity context. Activity context is associated with to the activity and can be destroyed if the activity is destroyed -- there may be multiple activities (more than likely) with a single application. And sometimes you absolutely need the activity context handle. For example, should you launch a new activity, you need to use activity context in its Intent so that the new launching activity is connected to the current activity in terms of activity stack. However, you may use application's context too to launch a new activity but then you need to set flag Intent.FLAG_ACTIVITY_NEW_TASK in intent to treat it as a new task.

让我们考虑一些情况:

MainActivity。这是指MainActivity上下文,它扩展了Activity类,但是基类(Activity)也扩展了context类,所以它可以用来提供活动上下文。 getBaseContext()提供活动上下文。 getApplication()提供应用程序上下文。 getApplicationContext()也提供了应用程序上下文。

欲了解更多信息,请点击此链接。


我使用这个表来指导何时使用不同类型的上下文,如应用程序上下文(即:getApplicationContext())和活动上下文,以及BroadcastReceiver上下文:

所有的优点去原作者这里获得更多信息。


我想知道为什么不使用应用程序上下文的每一个操作,它支持。最后,它降低了内存泄漏和getContext()或getActivity()缺失空检查的可能性(当使用注入的应用程序上下文或通过静态方法从application获得时)。像哈克伯恩女士所说的只在需要的时候使用应用程序上下文这样的陈述,如果没有解释原因,对我来说似乎没有说服力。但我似乎找到了一个不明确的原因:

have found that there are issues on some Android version / device combinations that do not follow these rules. For instance, if I have a BroadcastReceiver that is passed a Context and I convert that Context to an Application Context and then try to call registerReceiver() on the Application Context there are many instances where this works fine, but also many instances where I get a crash because of a ReceiverCallNotAllowedException. These crashes occur on a wide range of Android versions from API 15 up to 22. https://possiblemobile.com/2013/06/context/#comment-2443283153

因为不能保证下表中应用程序上下文所支持的所有操作都能在所有Android设备上运行!