Context和Application的理解

####

Context的作用

context是用来提供上下文环境,可以通过它调用系统资源,调用系统服务,如context.startActivity

Context有几种

Application,Activity,Service

Activity继承自ContextThemeWrapper,

ApplicationSerivce继承自ContextWrapper类。

ContextWrapper内部有一个mBase属性,该类型为ContextImpl类型,它才是真正执行任务的对象,此处用了一个静态代理的方式

BroadcastReceiver是一个抽象类,不是Context类型,但是在onReceive方法中会传入一个context对象,当是动态广播的时候,这个传入的context是注册时的那个,当是静态广播的时候,传入的是以Application对象为mBase的ContextWrapper类型对象

ContentProvider也不是一个Context类型,但是它内部有一个context属性,该context属性是Application对象,需要提到的是,Application的attachBaseContext方法在contentProvider的onCreate方法之前执行 ,同时,Application的onCreate方法在contentProvider的onCreate方法之后执行

Context的区别

需要处理ui的继承ContextThemeWrapper 如Activity的context

不需要的继承ContextWrapper 如service和application的context

Context的创建过程

Application,Activity,Service的创建过程都是先调用构造方法,再调用attach方法,再调用onCreate方法,所以不能在构造方法中获取context对象

Activity Context 创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;

ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
 activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
r.assistToken, r.shareableActivityToken);
   if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
return activity;
}

Application Context 创建

1
2
3
4
5
   #ActivityThread.java
private void handleBindApplication(AppBindData data) {
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
mInstrumentation.callApplicationOnCreate(app);
}

Service Context 创建

1
2
3
4
5
6
7
8
9
10
    #ActivityThread.java
private void handleCreateService(CreateServiceData data) {
       Application app = packageInfo.makeApplicationInner(false, mInstrumentation);
ContextImpl context = ContextImpl.getImpl(service
.createServiceBaseContext(this, packageInfo));

service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
service.onCreate();
}

Android应用里面有多少个Context?

Activity个数+Application个数+service个数 ,多进程会有多个application