android Context意为上下文,是应用程序所在环境的一个信息描述,一个全局工具,可以创建服务,访问资源文件等。
Context本身是一个抽象类,他的实现类有很多个包括ContextImpl和ContextThemeWrapper。
通常大家会用Context来启动Service,发送广播,启动Activity和进行资源访问,这些功能都是通过ContextImpl实现的。
本以为Activity继承了ContextImpl,后来发现并不是那样的;Activity只是继承了ContextThemeWrapper,然而ContextThemeWrapper并没有干什么有用的事只是调用baseContext的方法,最好不的事是baseContext类型竟然让是Context类型,丝毫看不出和ContextImpl是否有联系;既然这样那么就要找出是谁为baseContext赋的值。
通过分析Activity的启动过程发现创建Activity的时候调用了一个名叫createBaseContextForActivity方法,该方法的实现就是创建ContextImpl实例
private Context createBaseContextForActivity(ActivityClientRecord r,2190 final Activity activity) {2191 ContextImpl appContext = new ContextImpl();2192 appContext.init(r.packageInfo, r.token, this);2193 appContext.setOuterContext(activity);21942195 // For debugging purposes, if the activity's package name contains the value of2196 // the "debug.use-second-display" system property as a substring, then show2197 // its content on a secondary display if there is one.2198 Context baseContext = appContext;2199 String pkgName = SystemProperties.get("debug.second-display.pkg");2200 if (pkgName != null && !pkgName.isEmpty()2201 && r.packageInfo.mPackageName.contains(pkgName)) {2202 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();2203 for (int displayId : dm.getDisplayIds()) {2204 if (displayId != Display.DEFAULT_DISPLAY) {2205 Display display = dm.getRealDisplay(displayId);2206 baseContext = appContext.createDisplayContext(display);2207 break;2208 }2209 }2210 }2211 return baseContext;2212 }Activity创建过程中为attach传入了ContextImpl实例,这样activity便和ContextImpl有了联系,也符合应用中Activity调用ContextImpl的实现的现象