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); 2194 2195 // For debugging purposes, if the activity's package name contains the value of 2196 // the "debug.use-second-display" system property as a substring, then show 2197 // 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的实现的现象