Nor*_*ldt 259 android this android-context
有很多关于这两种背景的帖子......但我仍然没有把它弄得恰到好处
据我所知到目前为止:每个都是它的类的一个实例,这意味着一些程序员建议你this.getApplicationContext()
尽可能经常使用,以免"泄漏"任何内存.这是因为另一个this
(获取Activity
实例上下文)指向Activity
每次用户倾斜手机或离开应用程序等时被销毁的内容.显然垃圾收集器(GC)没有捕获,因此使用太多内存..
但是,任何人都可以提出一些非常好的编码示例,它们是正确的使用this
(获取当前Activity
实例的上下文)并且应用程序上下文将是无用的/错误的吗?
Com*_*are 396
getApplicationContext()
几乎总是错的.Hackborn女士(等等)已经非常明确,你只用getApplicationContext()
当你知道为什么你使用getApplicationContext()
,只有当你需要使用getApplicationContext()
.
坦率地说,"一些程序员"使用getApplicationContext()
(或者getBaseContext()
,在较小程度上),因为他们的Java经验是有限的.他们实现一个内部类(例如,OnClickListener
用于Button
在Activity
)和需要Context
.他们使用或获取一个对象,而不是MyActivity.this
用来获取外部类.this
getApplicationContext()
getBaseContext()
Context
只有getApplicationContext()
当您知道自己需要的Context
东西可能比Context
您可能使用的任何其他东西更长时,您才会使用.场景包括:
getApplicationContext()
如果你需要一些与Context
自身具有全局范围的东西,请使用.getApplicationContext()
例如,我使用WakefulIntentService
静态WakeLock
来用于服务.由于这WakeLock
是静态的,我需要Context
得到在PowerManager
创建它,它是最安全的使用getApplicationContext()
.
使用getApplicationContext()
时,您绑定到一个Service
从Activity
,如果你希望将传递ServiceConnection
(即句柄绑定)之间Activity
通过实例onRetainNonConfigurationInstance()
.Android通过这些内部跟踪绑定,ServiceConnections
并保存对Contexts
创建绑定的引用.如果你绑定了Activity
,那么新Activity
实例将引用ServiceConnection
一个对旧的隐式引用Activity
,而旧的Activity
不能被垃圾收集.
一些开发人员使用Application
他们自己的全局数据的自定义子类,他们通过它们检索getApplicationContext()
.这当然是可能的.我更喜欢静态数据成员,如果没有其他原因,你只能拥有一个自定义Application
对象.我使用自定义Application
对象构建了一个应用程序,发现它很痛苦.哈克伯恩女士也同意这一立场.
以下是不在getApplicationContext()
任何地方使用的原因:
它不是一个完整的Context
,支持一切Activity
.你将尝试用它做的各种事情Context
都会失败,主要与GUI有关.
它可能会造成内存泄漏,如果Context
from getApplicationContext()
保留在您不能清理的调用所创建的内容上.随着Activity
,如果持有到的东西,一旦Activity
得到垃圾收集,一切冲走了.该Application
对象在您的过程的生命周期中保留.
And*_*Jay 47
我认为SDK网站上有很多文档记录很少,这就是其中之一.我要提出的主张是,似乎最好默认使用应用程序上下文,并且只在需要时才使用活动上下文.我见过你需要一个活动上下文的唯一地方是进度对话框.SBERG412声称您必须为toast消息使用活动上下文,但Android文档清楚地显示正在使用的应用程序上下文.由于这个Google示例,我总是使用应用程序上下文进行祝酒.如果这样做是错误的,那么谷歌就把球丢了.
这里有更多的思考和评论:
对于Toast消息,Google Dev Guide使用应用程序上下文并明确说明使用它: Toast Notifications
在Dev指南的对话框部分中,您会看到AlertDialog.Builder使用应用程序上下文,然后进度条使用活动上下文.谷歌没有解释这一点. 对话框
使用应用程序上下文似乎是一个很好的理由,当您想要处理配置更改(如方向更改)时,您希望保留需要像Views这样的上下文的对象.如果你看这里:运行时更改 有一个关于使用活动上下文的警告,这可能会造成泄漏.使用具有要保留的视图的应用程序上下文(至少这是我的理解)可以避免这种情况.在我正在编写的应用程序中,我打算使用应用程序上下文,因为我试图在方向更改上保留一些视图和其他内容,并且我仍然希望在方向更改时销毁和重新创建活动.因此,我必须使用应用程序上下文不会导致内存泄漏(请参阅避免内存泄漏).对我而言,似乎有很多充分的理由使用应用程序上下文而不是活动上下文,对我来说,几乎看起来你会比活动上下文更频繁地使用它.这就是我经历过的许多Android书籍似乎都在做的事情,而这就是我见过的很多Google的例子.
谷歌文档确实使得在大多数情况下使用应用程序上下文看起来非常好,实际上比在他们的示例中使用活动上下文更频繁(至少我见过的例子).如果使用应用程序上下文确实是一个问题,那么谷歌真的需要更加重视这一点.他们需要说清楚,他们需要重做他们的一些例子.我不会完全归咎于没有经验的开发人员,因为权威(谷歌)真的让它看起来好像使用应用程序上下文不是问题.
Zoh*_*han 11
使用哪种上下文?
上下文有两种类型:
应用程序上下文与应用程序相关联,并且在应用程序的整个生命周期中始终保持相同 - 它不会更改.因此,如果您正在使用Toast,则可以使用应用程序上下文甚至活动上下文(两者),因为toast可以在应用程序中的任何位置显示,并且不会附加到特定窗口.但是有许多例外,一个例外是当您需要使用或传递活动上下文时.
活动上下文与活动相关联,如果活动被销毁,则可以销毁活动上下文 - 单个应用程序可能存在多个活动(很可能).有时你绝对需要活动上下文句柄.例如,如果启动新活动,则需要在其Intent中使用活动上下文,以便新的启动活动根据活动堆栈连接到当前活动.但是,您也可以使用应用程序的上下文来启动新活动,但是您需要Intent.FLAG_ACTIVITY_NEW_TASK
在意图中设置标记以将其视为新任务.
让我们考虑一些情况:
MainActivity.this
指的是MainActivity上下文,它扩展了Activity类,但基类(activity)也扩展了Context类,因此它可以用来提供活动上下文.
getBaseContext()
提供活动背景.
getApplication()
提供应用背景.
getApplicationContext()
还提供应用程序上下文
有关更多信息,请查看此链接.
我想知道为什么不对它支持的每个操作使用应用程序上下文。最后,它降低了内存泄漏的机会,并且减少了对getContext()或getActivity()的空检查(使用注入的应用程序上下文或通过Application的静态方法获取时)。像Hackborn女士所说的仅在需要时才使用Application Context的声明,在没有解释原因的情况下似乎对我没有说服力。但是,似乎我发现了一个失败的原因:
已发现某些Android版本/设备组合存在一些不遵循这些规则的问题。例如,如果我有一个传递了上下文的BroadcastReceiver,然后将该上下文转换为Application Context,然后尝试在Application Context上调用registerReceiver(),则有很多实例可以很好地工作,但也有很多实例可以因ReceiverCallNotAllowedException而导致崩溃。这些崩溃发生在从API 15到22的各种Android版本上 。https://possiblemobile.com/2013/06/context/#comment-2443283153
因为不能保证下表中描述的由Application Context支持的所有操作都可以在所有Android设备上使用!
归档时间: |
|
查看次数: |
71239 次 |
最近记录: |