android应用程序承载的基础Context,单词翻译为上下文,背景,环境;它是android应用程序存在的环境,许多时候我们在启动一个Activity,Service ,发送广播,获取文件、图片、字符串,操作数据库等的时候,都需要拿到这个Context的对象,它是我们经常接触而且能力超强大的一个对象,我们可以简单的认为当你启动一个Activty或者Service的时候,就进入了一个android的环境,每一个环境下都是单独的,一个原生态的android程序就将在这个环境下愉快的生存。
我们经常会通过Activity,Application,Service中调用许许多多android api的方法,然而这些方法都会与Context有关,然而我们查看Context这个类的时候,发现这个类仅仅只是一个声明了许多抽象方法的抽象类;好吧,那我们就反过来看,从Activity,Service,Application入手,发现它们都是ContextWrapper的子类。而ContextWrapper又是Context的包装类,内部包含一个Context的引用,指向这个Context的具体实现类是ContextImpl。ContextWrapper内部的所有方法直接调用ContextImpl对应的方法。
查看源码,通过分析整理Context家族图如下:
所有的引用都指向了ContextImpl这个类,看看我们经常见到那些方法到底做了些什么:
1,startActivity:
warnIfCallingFromSystemProcess();//该方法警告不要通过系统进程调用该方法
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { throw new AndroidRuntimeException( "Calling startActivity() from outside of an Activity " + " context requires the FLAG_ACTIVITY_NEW_TASK flag." + " Is this really what you want?");
mMainThread.getInstrumentation().execStartActivity(getOuterContext(), mMainThread.getApplicationThread(), null, (Activity)null, intent, -1, options);
//mMainThread就是ActivityThread,一个新应用程序的开始就是从该类开始的
//getInstrumentation()返回的Instrumentaion对象,该类主要负责组件的创建,监控系统与应用的所有交互
代码走到这里,发现其实ContextImpl把启动Activity的事情都交给了ActivityThread去完成了。
2,getResources:
@Override
public Resources getResources() {
return mResources;
}
void setResources(Resources r) {
if (r instanceof CompatResources) {
((CompatResources) r).setContext(this);
}
mResources = r;
}
平常我们使用到各种图片资源,是放在ContextImpl实例下的一个全局mResources对象,Context本身只是提供能够获取它的环境
3,startService
直接上ContextImpl部分的源码:
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
public ComponentName startForegroundService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, true, mUser);
}
// 最终的入口都在这个方法中
// foreground service只是传参requireForeground为true,普通service为false
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
// binder call至ams
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
} else if (cn.getPackageName().equals("?")) {
throw new IllegalStateException(
"Not allowed to start service " + service + ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
ContextImpl做了3件,
a)warnIfCallingFromSystemProcess();//该方法警告不要通过系统进程调用该方法
b)调用ActivityManager启动service
c)对启动结果做出分析判断
总结,还是没有启动service,交给了ActivityManager处理了,只是做了启动结果的分析
通过以上总结发现Context的实现类也只是做了一些资源整合的事情,它实际更像Android系统环境里面的管家,我们需要进入Android的系统环境里面,都需要经过管家同意以及操作才能完成!!!