Context 到底是什么?
一个Context意味着一个场景,一个场景就是我们和软件进行交互的一个过程。
从安卓程序的角度来看,其实一个Activity就是一个Context,一个Service也是一个Context。
一个app其实可以理解成一个大环境,在这个环境里,可以切换到不同的场景,比如你早上先去办公室上班,中午到饭馆吃饭,就是在不同的场景了。
各个Context 类的关系图
先贴个图

Context 作用是啥
有什么用?要看它能做啥,看看主要提供了哪些接口了。
| 四大组件相关 | ![]() |
| 获取系统/应用资源 | ![]() |
| 获取应用相关信息 | ![]() |
| 文件相关 | ![]() |
| 数据库相关 | ![]() |
| 其它 | ![]() |
还挺多的,看起来管得挺多,四大组件都管着,像个 Application 大管家。
| 管的谁? | 哪些事? |
|---|---|
| 四大组件 | 包括启动 Activity、Broadcast、Service,获取 ContentResolver 等 |
| 获取系统/应用资源 | 包括 AssetManager、PackageManager、Resources、System Service 以及 color、string、drawable 等 |
| 数据库(SQLite)相关 | 包括打开数据库、删除数据库、获取数据库路径等 |
| 其它辅助功能 | 比如设置 ComponentCallbacks,即监听配置信息改变、内存不足等事件的发生 |
ContextImpl 和 ContextWrapper 有啥区别?
看下ContextWrapper的源码吧
/**
* Proxying implementation of Context that simply delegates all of its calls to
* another Context. Can be subclassed to modify behavior without changing
* the original Context.
*/
public class ContextWrapper extends Context {
Context mBase; // 注意这个mBase
public ContextWrapper(Context base) {
mBase = base;
}
/**
* Set the base context for this ContextWrapper. All calls will then be
* delegated to the base context. Throws
* IllegalStateException if a base context has already been set.
*
* @param base The new base context for this wrapper.
*/
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
/**
* @return the base context as set by the constructor or setBaseContext
*/
public Context getBaseContext() {
return mBase; // 这就是Base Context 了
}
@Override
public AssetManager getAssets() {
return mBase.getAssets();
}
@Override
public Resources getResources() {
return mBase.getResources();
}
@Override
public PackageManager getPackageManager() {
return mBase.getPackageManager();
}
...
@Override
public Context getApplicationContext() {
return mBase.getApplicationContext();
}
...
ContextImpl呢?
/**
* Common implementation of Context API, which provides the base
* context object for Activity and other application components.
*/
class ContextImpl extends Context {
private int mThemeResource = 0;
private Resources.Theme mTheme = null;
private @NonNull Resources mResources;
// 用于创建 Activity Context
static ContextImpl createActivityContext(...) {
ContextImpl context = new ContextImpl(...);
context.setResources(resourcesManager.createBaseActivityResources(...));
return context;
}
// 用于创建 Application Context、Service Context
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
ContextImpl context = new ContextImpl(...);
context.setResources(packageInfo.getResources());
return context;
}
private static Resources createResources(...) {
return ResourcesManager.getInstance().getResources(...);
}
// ContextThemeWrapper 没有重写父类的 setResources
// 因此会调用 mBase 的 setResources,即和 ContextImpl 的行为一样
void setResources(Resources r) {
if (r instanceof CompatResources) {
((CompatResources) r).setContext(this);
}
mResources = r;
}
@Override
public Resources getResources() {
return mResources;
}
...
| Class | Diff |
|---|---|
| ContextImpl | 真正实现了Context中所有的函数 (真正厉害的!) |
| ContextWrapper | Context 的代理类,所有的操作都是通过内部成员 mBase 完成的 |
| ContextThemeWrapper | 内部包含了与主题相关的接口,有自己的 Theme 以及 Resource,并且 Resource 可以传入自己的配置初始化 |
P.S.
主题是啥?
就是指在AndroidManifest.xml中通过 android:theme 为 Application 或者 Activity 指定的主题。
只有Activity才需要主题,Service是默默的后台工作者,不需要穿的那么鲜艳,所以Service直接继承 ContextWrapper 就好了。
Activity、Service、Application 各自的Context有啥区别?
不同组件创建ContextImpl的方式:
| API | |
|---|---|
| Activity | 调用 createBaseContextForActivity |
| Service/Application | 调用 createAppContext |
| Provider | 调用 createPackageContext |
| BroadcastReceiver | 直接从 Application.getBaseContext() 来获取 ContextImpl 对象 |





