1.Context介绍
我们在实际开发中,当我们需要访问资源或者启动一个Activity都会用到Context。那么这个Context到底是什么呢?它代表当前程序的运行环境。Context是一个抽象类,里面定义了很多有关应用程序环境的全局信息的接口。通过这个类,我们可以访问访问应用程序的资源和类;以及对应用程序级操作的调用,例如启动Activity、广播和接收intent等。
2.Context的结构
Context是一个抽象类,来看下它的具体实现类:
它的实现类有两个:ContextImpl.java、ContextWrapper.java,但真正的实现类是ContextImpl。
ContextImpl
Context的真正实现类,访问资源及启动Activity、Service等操作的具体实现都在这个类里。
ContextWrapper
Context的包装类,它里面的方法都是交由ContextImpl去实现的,主要作用是对Context进行拓展和定制。
frameworks/base/core/java/android/content/ContextWrapper.java
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
@Override
public Resources getResources() {
return mBase.getResources();
}
@Override
public void startActivities(Intent[] intents) {
mBase.startActivities(intents);
}
mBase实际是ContextImpl类型对象,通过attachBaseContext()方法来指定mBase对象,可以看出ContextWrapper内部都是通过包装mBase来实现拓展功能,而我们可以通过对mBase进行包装来对Context进行拓展和定制。
从上图中可以看到ContextWrapper也有几个子类:Application.java、Service.java、ContextThemeWrapper.java
ContextThemeWrapper
ContextThemeWrapper是ContextWrapper的拓展类,里面重写了一些关于Theme的方法。它的作用是为Context
对象提供一个特定的主题,只有Activity需要主题,所以Activity继承自ContextThemeWrapper。
因为ContextThemeWrapper继承自ContextWrapper,所以我们可以通过包装Context对象来对主题进行拓展和定制,而不需要修改原本的Context类。
所以Activity、Service、Application本质上也都可以通过包装mBase来实现功能的拓展。
总结一下这些类之间的关系:抽象类Context定义了具体的接口;ContextImpl具体实现了Context定义的所有方法;ContextWrapper继承了Context接口,并包装了具体实现ContextImpl;ContextThemeWrapper继承了ContextWrapper并扩展了替换Theme的功能。