Context的中文翻译为:语境; 上下文; 背景; 环境,在开发中我们经常说称之为“上下文”
在语文中,我们可以理解为语境,在程序中,我们可以理解为当前对象在程序中所处的一个环境,一个与系统交互的过程。
比如微信聊天,此时的“环境”是指聊天的界面以及相关的数据请求与传输,
Context在加载资源、启动Activity、获取系统服务、创建View等操作都要参与。
1.1context是什么?
一个Activity就是一个Context,一个Service也是一个Context。
Android程序员把“场景”抽象为Context类,他们认为用户和操作系统的每一次交互都是一个场景,
比如打电话、发短信,这些都是一个有界面的场景,
还有一些没有界面的场景,比如后台运行的服务(Service)。
一个应用程序可以认为是一个工作环境,用户在这个环境中会切换到不同的场景,
这就像一个前台秘书,她可能需要接待客人,可能要打印文件,还可能要接听客户电话,而这些就称之为不同的场景,前台秘书可以称之为一个应用程序。
1.2 四大组件不能随便new一个对象
Activity,Service,Broadcast Receiver,Content Provider这四大组件,不能随便new一个对象
四大组件必须工作在Context环境下
那Button,TextView,LinearLayout这些控件呢,可以new一个对象,
但必须工作在Context环境下,所以Button mButton=new Button(Context)是可以的。
1.3 一个应用程序有几个Context
在应用程序中Context的具体实现子类就是:Activity,Service,Application。
那么Context数量=Activity数量+Service数量+1。
Broadcast Receiver,Content Provider并不是Context的子类,
他们所持有的Context都是其他地方传过去的,所以并不计入Context总数。
2.1 Context能干什么?
这个就实在是太多了,弹出Toast、启动Activity、启动Service、发送广播、操作数据库等等都需要用到Context
TextView tv = new TextView(getContext());
ListAdapter adapter = new SimpleCursorAdapter(getApplicationContext(), ...);
AudioManager am = (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE);getApplicationContext().getSharedPreferences(name, mode);
getApplicationContext().getContentResolver().query(uri, ...);
getContext().getResources().getDisplayMetrics().widthPixels * 5 / 8;
getContext().startActivity(intent);
getContext().startService(intent);
getContext().sendBroadcast(intent);
2.2 Context作用域
凡是跟UI相关的,都应该使用Activity做为Context来处理;
其他的一些操作,Service,Activity,Application等实例都可以,
当然了,注意Context引用的持有,防止内存泄漏。
3.1 如何获取Context
通常我们想要获取Context对象,主要有以下四种方法
1:View.getContext,返回当前View对象的Context对象,通常是当前正在展示的Activity对象。
2:Activity.getApplicationContext,获取当前Activity所在的(应用)进程的Context对象,通常我们使用Context对象时,要优先考虑这个全局的进程Context。
3:ContextWrapper.getBaseContext():用来获取一个ContextWrapper进行装饰之前的Context,可以使用这个方法,这个方法在实际开发中使用并不多,也不建议使用。
4:Activity.this 返回当前的Activity实例,如果是UI控件需要使用Activity作为Context对象,但是默认的Toast实际上使用ApplicationContext也可以。
3.2 Context引起的内存泄露
一般Context造成的内存泄漏,几乎都是当Context销毁的时候,却因为被引用导致销毁失败,
而Application的Context对象可以理解为随着进程存在的,所以我们总结出使用Context的正确姿势:
1:当Application的Context能搞定的情况下,并且生命周期长的对象,优先使用Application的Context。
2:不要让生命周期长于Activity的对象持有到Activity的引用。
3:尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,
如果使用静态内部类,将外部实例引用作为弱引用持有。
4 总结
总之Context在Android系统中的地位很重要,它几乎无所不能,
但它也不是你想用就能随便用的,谨防使用不当引起的内存问题。