1、sdk当中关于Context的介绍

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.

http://developer.android.com/reference/android/content/Context.html

Context提供了关于应用环境全局信息的接口。它是一个抽象类,它的由整个Android应用程序所实现。它允许获取应用当中特定的资源和类,同时允许调用应用级的操作,如启动Activity,broadcasting和接收intents等等。

从以上的描述当中,我们基本获得不了什么信息,更无法理性的认识Context。

我们再来看看Context是子类和部分方法如下:

               

其中Application、Activity、Service等我们在开发当中常用的类,都是其子类,我们在这里也无法认识到它的作用。右图,我们可以看到,我们平时用到的startActivty();startService();等方法都在这里,在这里,我们可以看到Context的第一个作用:

2、第一个作用

Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system.

他提供一个全局的接口,并且这些接口由Android应用程序当中特定的类实现。

我们再来看看Activity的源码:

/** * Launch a new activity. You will not receive any information about when * the activity exits. This implementation overrides the base version, * providing information about * the activity performing the launch. Because of this additional * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not * required; if not specified, the new activity will be added to the * task of the caller. * * <p>This method throws {@link android.content.ActivityNotFoundException} * if there was no Activity found to run the given Intent. * * @param intent The intent to start. * * @throws android.content.ActivityNotFoundException * * @see #startActivityForResult */ @Override public void startActivity(Intent intent) { startActivityForResult(intent, -1); }

  public void startActivityForResult(Intent intent, int requestCode) {if (mParent == null) {Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode);if (ar != null) {mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),ar.getResultData());}if (requestCode >= 0) {// If this start is requesting a result, we can avoid making// the activity visible until the result is received.  Setting// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the// activity hidden during this time, to avoid flickering.// This can only be done when a result is requested because// that guarantees we will get information back when the// activity is finished, no matter what happens to it.mStartedActivity = true;}} else {mParent.startActivityFromChild(this, intent, requestCode);}}

这里,startActivity()的实现调用了Context中没有的startActivityForResult方法得以实现开启新的窗体的Activity的功能。

我们再看看我们平时用到的startService方法,非常遗憾我们没有在Activity当中找到startService的实现,但是我们继续往上找,找到了ContentWrapper时,我们找到了startService的实现

@Override public ComponentName startService(Intent service) { return mBase.startService(service); } 类似的Application,service等,都可以找到其相应的函数的实现。Context功能之一就是将常用的公共方法抽取出来,然后由各个组件实现,这真是第一句话的意思。

3、第二个作用

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.

它允许获取应用当中特定的资源和类,同时允许调用应用级的操作,如启动Activity,broadcasting和接收intents等等。其实该类为LONG型,类似Win32中的Handle句柄,很多方法需要通过 Context才能识别调用者的实例,比如说Toast的第一个参数就是Context,一般在Activity中我们直接用this代替,代表调用者的 实例为Activity,而到了一个button的onClick(View view)等方法时,我们用this时就会报错,所以我们可能使用ActivityName.this来解决,主要原因是因为实现Context的类主要有Android特有的几个模型,Activity、Service以及BroadcastReceiver。

对于以上几句话的理解,我们可以看看TextView的构造函数

可以看到起参数为Context但是我们在实际开发当中

TextView text1 = new TextView(this); TextView text2 = new TextView(getApplication()); TextView text3 = new TextView(getApplicationContext()); 这两种定义都可以实现。this表示这个类的某个实例,而getApplicationContext()得到的是Context(),两个风马牛不相及的事物为什么能放在TextView的构造函数里,而不报错呢,这就是Context的第二个作用,句柄。标识应用程序中的不同对象和同类对象中的不同的实例。

4、两种不同的Context

正如上段代码,getApplication();getApplicationContext();前者是在Activity当中定义的,而后者是在Context当中定义的。
两者的说明分别为:
这里,我们看到了两种不同的Context:Activity所拥有的Context和全局的Context。
这是两种不同的context,也是最常见的两种。第一种中context的生命周期与Application的生命周期相关的,context随着Application的销毁而销毁,伴随application的一生,与activity的生命周期无关。第二种中的context跟Activity的生命周期是相关的,但是对一个Application来说,Activity可以销毁几次,那么属于Activity的context就会销毁多次。至于用哪种context,得看应用场景,个人感觉用Activity的context好一点,不过也有的时候必须使用Application的context。application context可以通过Context.getApplicationContext或者Activity.getApplication方法获取。

5、内存泄露

在android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。比如一个activity的onCreate:
protected void onCreate(Bundle state) { super.onCreate(state); TextView label = new TextView(this); //传递context给view control label.setText("Leaks are bad"); setContentView(label); }把activity context传递给view,意味着view拥有一个指向activity的引用,进而引用activity占有的资源:view hierachy, resource等。这样如果context发生内存泄露的话,就会泄露很多内存。这里泄露的意思是gc没有办法回收activity的内存。Leaking an entire activity是很容易的一件事。
当屏幕旋转的时候,系统会销毁当前的activity,保存状态信息,再创建一个新的。
比如我们写了一个应用程序,它需要加载一个很大的图片,我们不希望每次旋转屏 幕的时候都销毁这个图片,重新加载。实现这个要求的简单想法就是定义一个静态的Drawable,这样Activity 类创建销毁它始终保存在内存中。实现类似:
public class myactivity extends Activity { private static Drawable sBackground; protected void onCreate(Bundle state) { super.onCreate(state); TextView label = new TextView(this); label.setText("Leaks are bad"); if (sBackground == null) { sBackground = getDrawable(R.drawable.large_bitmap); } label.setBackgroundDrawable(sBackground);//drawable attached to a view setContentView(label); } }这段程序看起来很简单,但是却问题很大。当屏幕旋转的时候会有leak(即gc没法销毁activity)。我们刚才说过,屏幕旋转的时候系统会销毁当前的activity。但是当drawable和view关联后,drawable保存了view的 reference,即sBackground保存了label的引用,而label保存了activity的引用。既然drawable不能销毁,它所 引用和间接引用的都不能销毁,这样系统就没有办法销毁当前的activity,于是造成了内存泄露。gc对这种类型的内存泄露是无能为力的。避免这种内存泄露的方法是避免activity中的任何对象的生命周期长过activity,避免由于对象对 activity的引用导致activity不能正常被销毁。我们可以使用application context。application context伴随application的一生,与activity的生命周期无关。application context可以通过Context.getApplicationContext或者Activity.getApplication方法获取。

6、避免context相关的内存泄露,记住以下几点:

  1. 不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的
  2. 对于生命周期长的对象,可以使用application context
  3. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化

7、制造Application context的方法

Java里面通常是用一个static的变量(例如singleton之类的)来同步activity之间(程序里面类之间)的状态。在android里面比较靠谱的做法是用application context来关联这些状态。
每个activity都是context,里面包含了运行时的状态。同样application也有一个context,android会保证这个context是唯一的实例。
做一个你自己的application context需要继承android.app.Application,然后在app的manifest里面说明这个类。android会自动帮你创建你这个类的实例,接着你用Context.getApplicationContext()方法就能在各个activity里面获得这个application context了。
class MyApp extends Application {     private String myState;     public String getState(){     return myState;   }   public void setState(String s){     myState = s;   } }   class Blah extends Activity {     @Override   public void onCreate(Bundle b){     ...     MyApp appState = ((MyApp)getApplicationContext());     String state = appState.getState();     ...   } }
小文章,边看边写,欢迎纠错。
参考文章:http://www.igniu.com/?p=215
http://blog.csdn.net/aomandeshangxiao/article/details/7008636

转载于:https://www.cnblogs.com/snowberg/archive/2012/04/22/2468506.html

Android中的Context理解相关推荐

  1. android中获取context对象

    在Android中获取context对象 方法一: 先在activity中获取context对象: Context context = MainActivity.this; 哪个类要用到此contex ...

  2. Android 中的context, service,active和intent使用详解

    在一个Android应用中,主要是由四种组件组成的,这四种组件分别是Context,Activity,Intent,Service. Content被译为上下文,是应用程序中心,应用程序所有功能可以通 ...

  3. android studio创建一个类继承application_带你全方位了解Android中的Context

    这道题想考察什么? 是否熟悉Context类结构 是否熟悉Application,Activity,Service和Context的依赖关系 Application,Activity,Service中 ...

  4. android中获取context的多种方法的区别(this,getbascontext(),getApplicationcontext())

    本文转自:http://www.eoeandroid.com/thread-171104-1-1.html 原文转自:http://stackoverflow.com/questions/102697 ...

  5. Android中的context

    2019独角兽企业重金招聘Python工程师标准>>> Context字面意思是上下文,位于framework package的android.content.Context中,其实 ...

  6. Android 中的 Context

    主要的功能是加载和访问资源(Context通常用来获取APP资源,创建UI,获取系统Service服务,启动Activity,绑定Service,发送广播,获取APP信息等) 如何理解: 我们可以理解 ...

  7. android tag的作用,Android中的Context的作用(2)

    ContextImpl关键成员和函数 /** * Common implementation of Context API, which provides the base * context obj ...

  8. 对android中Zygote的理解

    谈谈对Zygote的简单理解 1. Zygote的作用 启动SystemServer 孵化应用进程 SystemServer也是通过Zygote启动的,因为它也需要Zygote的资源:常用类,JNI函 ...

  9. java 单例 内存释放_周小抒 – 梦想仗剑走天涯 | Android中关于Context单例模式引起的内存泄漏以及解决方案...

    内存溢出与内存泄漏的区别: 内存溢出是由于应用所消耗的内存或者应用申请的内存超出了虚拟机分配的内存,也就是内存不够用了. 内存泄漏是某个不再使用对象由于被其他实例引用,导致不能被GC回收,而导致的内存 ...

最新文章

  1. OC中的NSArray和NSMutableArray、NSDictionary和NSMutableDictionary用法
  2. 多线程:无锁、偏向锁、轻量锁、重量级锁
  3. MyBatis延迟加载及在spring中集成配置
  4. Spark 性能调优-内存设置-GC设置
  5. Java并发-ThreadLocal
  6. FreeChart柱状图中如何取消柱子的倒影
  7. 数据分析学习笔记—python函数、异常与处理
  8. Matlab Tricks(十一)—— padarray 关于边缘成镜像对称
  9. TCPIP详解 卷一核心概念整理
  10. ZTEBA601.android5.1,中兴Blade A601线刷刷机教程_中兴BA601线刷包_救砖刷机包
  11. 鹿客、小米、智汀、德施曼这几款热门智能门锁测评:谁最安全?谁最便捷?
  12. 解决Win10自动打开代理问题
  13. thinkphp使用编辑器kindeditor
  14. ios网易大白Crash自动防护
  15. 读书《AB实验:科学归因与增长的利器》(刘玉凤)
  16. 【uni-app高级实战】手把手带你学习一个纯实战复杂项目的开发1/100
  17. 用EXCEL分析《亚马逊智能产品评论》
  18. 学习spring英文官方文档方法
  19. 《大西洋月刊》2014-2020年电子版合集| The Atlantic
  20. Android-适配各国语言、屏幕尺寸、系统版本及常见适配方法总结

热门文章

  1. Mr.J--JS事件监听(捕获冒泡)
  2. Luogu 4491 [HAOI2018]染色
  3. [bzoj 1398] Vijos1382寻找主人 Necklace 解题报告(最小表示法)
  4. Oracle11g:分区表数据操作出现ORA-14400异常处理
  5. C#基础视频教程4.3 如何编写简单的计算器
  6. Educational Codeforces Round 1(D. Igor In the Museum) (BFS+离线访问)
  7. 【转载】java中Date与String的相互转化
  8. 整理下STL algorithms(3)
  9. 自定义用户控件显示属性分类、描述、默认值
  10. webpack 的webpack.config文件配置css-loader,style-loader注意的问题