柳月微微 發表於 2019-6-26 21:00:00

Android 开发:Context的使用

<p>Android开发经常需要使用Context来启动Activity,或者打开SharedPreferences,或者构建一个Dialog。最近老是用到getContext(),getApplicationContext(),this等,来获取Context,故写此文来理清思路。确定好需要Context的时候,究竟用哪个函数。</p>
<h2 id="context">Context</h2>
<p>什么是Context呢?</p>
<p>个人的理解是:Context就是上下文,换句话说就是运行的环境。它可以用来新建对象,访问资源。</p>
<p>官方的参考文档,只有一段:</p>
<blockquote>
<p>Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.</p>
</blockquote>
<p>这么一段说了3件事情(简单的翻译如下):</p>
<ol>
<li>它是获取应用环境信息的接口。</li>
<li>它是一个抽象类,实现由安卓系统提供。</li>
<li>它允许访问application-specific的资源和类;执行应用级别的操作,比如开启一个activity。</li>
</ol>
<h2 id="获取context的方法">获取Context的方法</h2>
<p>获取Context的方法有如下几种:</p>
<ol>
<li>Activity类中使用this关键字</li>
<li>SomeActivity.this</li>
<li>在Fragment中,可以getActivity()</li>
<li>getContext()</li>
<li>getApplicationContext()</li>
<li>getBaseContext()</li>
</ol>
<p>那么这几种获取Context对象的方式有什么异同?</p>
<p>首先将这些方法分类,按照使用的地方分类:</p>
<p>在Activity中可以使用的:</p>
<ol>
<li>Activity类中使用this关键字</li>
<li>SomeActivity.this</li>
<li>getApplicationContext()</li>
<li>getBaseContext()</li>
</ol>
<p>在Fragment中可以使用的:</p>
<ol>
<li>getContext()</li>
<li>getActivity()</li>
</ol>
<p>在View中可以使用的:</p>
<ol>
<li>getContext()</li>
</ol>
<h3 id="它们各自的含义">它们各自的含义</h3>
<p>在Activity类中使用this关键字,等同于SomeActivity.this。</p>
<p>getApplicationContext() 获取整个应用的Context,获取的对象存活周期和应用一样长。</p>
<p>getContext() View中获取的是当前活动的Activity,Fragment中返回与之关联的Context</p>
<p>getActivity() 返回当前Fragment相关联的Activity</p>
<p>getBaseContext() 获取ContextWrapper的原始context</p>
<p>不管是Application,还是Activity,它们都继承了Context。</p>
<h2 id="避免context引起的内存泄漏">避免Context引起的内存泄漏</h2>
<p>由Context引起的内存泄漏主要由两个原因:</p>
<ol>
<li>引用了这个Context的对象存活时间长过传入的activity。</li>
<li>成员内部类和匿名内部类隐式持有外部类的对象导致。</li>
</ol>
<p>第一种情况好理解,当activity销毁的时候,还有对象引用了这个activity,那么GC不会回收这个activity。<br>
第二种情况的原因,参见链接4。讲的主要是内部类会隐式的持有外部类的对象导致GC不回收这个activity。在安卓中可能发生内存泄漏的地方是,一个activity里面有一个Runnable的运行还没结束,这个activity已经销毁了。但是这个activity被Runnabl隐式地持有,导致activity无法被回收。</p>
<p>既然如此,那就干脆不要用this好了!用getApplicationContext()不就好了?</p>
<p>但是,getApplicationContext()有其弊端!</p>
<p>链接3解释了不用getApplicationContext()的原因:它不是完整的Context。可能导致一些GUI相关的问题。比如AlertDialog.Builder不能使用getApplicationContext(),因为dialog需要一些主题相关的信息,而Application并不包含这些信息。(You need to use a Theme.AppCompat theme (or descendant) with this activity)</p>
<p><strong>那么什么时候用getApplicationContext(),什么时候用this?</strong><br>
一般而言,如果context不需要ui相关的操作,就用getApplicationContext()。如果对象存活时间可能比activity长,考虑使用getApplicationContext()。其他情况,确保activity销毁前,取消引用activity,用this就好了。</p>
<h2 id="参考链接">参考链接</h2>
<ol>
<li>https://stackoverflow.com/questions/10641144/difference-between-getcontext-getapplicationcontext-getbasecontext-and#</li>
<li>https://juejin.im/post/58cb97e1128fe1006c84aafe</li>
<li>https://stackoverflow.com/questions/7298731/when-to-call-activity-context-or-application-context</li>
<li>https://blog.csdn.net/leunging/article/details/53080863</li>
</ol><br><br>
来源:https://www.cnblogs.com/zzk0/p/11093891.html
頁: [1]
查看完整版本: Android 开发:Context的使用