在android中我们经常遇到这样的情况,在创建一个对象的时候往往需要传递一个this参数,比如:语句 MyView mView = new MyView(this),要求传递一个this参数,这个this究竟指的是什么东西呢?其实这里的this指的就是当前的Activity.this,是这个语句所在的Activity的this。Activity.this取的是这个Activity的Context。
又比如说Toast的第一个参数就是Context,一般在Activity中我们直接用this代替,代表调用者的实例为Activity,而到了一个button的onClick(View view)等方法时,我们用this时就会报错,所以我们可能使用ActivityName.this来解决。
说了这么多,那么这个Context究竟是什么东西呢?它起到什么作用呢?
Context 按照英文字面意思就是"上下文",它位于位于framework package的android.content.Context中,其实该类为LONG型,类似于句柄。很多方法需要通过 Context才能识别调用者的实例。
SDK中对其说明如下:
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
Context,如果是直接从文档翻译过来,就真的是十足的专业了:提供应用环境全局信息的接口,并且这个接口是由抽象类实现的,它的执行被android系统所提供,允许我们获取以应用为特征的资源和类型,同时启动应用级的操作,如启动Activity,broadcasting和接收intent。
从上面描述可知三点,即:
它描述的是一个应用程序环境的信息,即上下文。
该类是一个抽象(abstract class)类,Android提供了该抽象类的具体实现类(后面我们会讲到是ContextIml类)。
通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作,例如:启动一个Activity,发送广播,接受Intent信息 等。
于是,我们可以利用该Context对象去构建应用级别操作(application-level operations) 。
Context继承关系如下:
1. Context类
路径: /frameworks/base/core/java/android/content/Context.java
说明: 抽象类,提供了一组通用的API。
public abstract class Context {
...
public abstract Object getSystemService(String name); //获得系统级服务
public abstract void startActivity(Intent intent); //通过一个Intent启动Activity
public abstract ComponentName startService(Intent service); //启动Service
//根据文件名得到SharedPreferences对象
public abstract SharedPreferences getSharedPreferences(String name,int mode);
...
}
2. ContextIml.java类
路径 :/frameworks/base/core/java/android/app/ContextImpl.java
说明:该Context类的实现类为ContextIml,该类实现了Context类的功能。请注意,该函数的大部分功能都是直接调用其属性mPackageInfo去完成,这点我们后面会讲到。
/**
* Common implementation of Context API, which provides the base
* context object for Activity and other application components.
*/
class ContextImpl extends Context{
//所有Application程序公用一个mPackageInfo对象
/*package*/ ActivityThread.PackageInfo mPackageInfo;
@Override
public Object getSystemService(String name){
...
else if (ACTIVITY_SERVICE.equals(name)) {
return getActivityManager();
}
else if (INPUT_METHOD_SERVICE.equals(name)) {
return InputMethodManager.getInstance(this);
}
}
@Override
public void startActivity(Intent intent) {
...
//开始启动一个Activity
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
}
}
3. ContextThemeWrapper类
路径:/frameworks/base/core/java/android/view/ContextThemeWrapper.java
说明:该类内部包含了主题(Theme)相关的接口,即android:theme属性指定的。只有Activity需要主题,Service不需要主题,所以Service直接继承于ContextWrapper类。
public class ContextThemeWrapper extends ContextWrapper {
//该属性指向一个ContextIml实例,一般在创建Application、Service、Activity时赋值
private Context mBase;
//mBase赋值方式同样有一下两种
public ContextThemeWrapper(Context base, int themeres) {
super(base);
mBase = base;
mThemeResource = themeres;
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
mBase = newBase;
}
}
Activity类 、Service类 、Application类本质上都是Context子类, 更多信息大家可以自行参考源代码进行理解。
在android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context。通常我们在各种类和方法间传递的是activity context。后面我们会慢慢逐一介绍。
一点补充:
getApplicationContext() 返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁。
Activity.this的context 返回当前activity的上下文,属于activity ,activity 摧毁他就摧毁。
getBaseContext() 返回由构造函数指定或setBaseContext()设置的上下文,一般不常用。