赞
踩
Activity—>ContextThemeWrapper—>ContextWrapper
@Override
public Object getSystemService(String name) {
return mBase.getSystemService(name);
}
frameworks/base/core/java/android/content/ContextWrapper.java
public class ContextWrapper extends Context {
public ContextWrapper(Context base) {
mBase = base;
}
}
frameworks/base/core/java/android/view/ContextThemeWrapper.java
public class ContextThemeWrapper extends ContextWrapper {
public ContextThemeWrapper() {
super(null);
}
public ContextThemeWrapper(Context base, @StyleRes int themeResId) {
super(base);
mThemeResource = themeResId;
}
public ContextThemeWrapper(Context base, Resources.Theme theme) {
super(base);
mTheme = theme;
}
}
frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper {
并没有构造函数
}
所以mBase 的赋值并不是通过构造函数赋值的
frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper {
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
newBase.setAutofillClient(this);
}
}
frameworks/base/core/java/android/app/Activity.java
final void attach(Context context, ActivityThread aThread, ....) {
attachBaseContext(context);
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mUiThread = Thread.currentThread();
.......
}
ActivityThread 和service 的context的都是在此类中赋值的
frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader(cl); } } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException("Unable to instantiate activity " + component + ": " + e.toString(), e); } ...... appContext.setOuterContext(activity); 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.configCallback); ...... }
frameworks/base/core/java/android/app/ContextImpl.java
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) { final int displayId; try { displayId = ActivityManager.getService().getActivityDisplayId(r.token); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } ContextImpl appContext = ContextImpl.createActivityContext( this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig); final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); String pkgName = SystemProperties.get("debug.second-display.pkg"); if (pkgName != null && !pkgName.isEmpty() && r.packageInfo.mPackageName.contains(pkgName)) { for (int id : dm.getDisplayIds()) { if (id != Display.DEFAULT_DISPLAY) { Display display = dm.getCompatibleDisplay(id, appContext.getResources()); appContext = (ContextImpl) appContext.createDisplayContext(display); break; } } } return appContext; }
frameworks/base/core/java/android/app/ContextImpl.java
static ContextImpl createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration) {
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName, activityToken, null, 0, classLoader);
final ResourcesManager resourcesManager = ResourcesManager.getInstance();
context.setResources(resourcesManager.createBaseActivityResources(activityToken, packageInfo.getResDir(), splitDirs, packageInfo.getOverlayDirs(), packageInfo.getApplicationInfo().sharedLibraryFiles, displayId, overrideConfiguration, compatInfo, classLoader));
context.mDisplay = resourcesManager.getAdjustedDisplay(displayId, context.getResources());
return context;
}
到此可以看出Activity 是在ContextImpl 中使用createActivityContext 创建了一个context,
service 的Context 也是同样的道理, 是基于 ContextImpl 的createAppContext 方法创建的
frameworks/base/core/java/android/app/ContextImpl.java
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
frameworks/base/core/java/android/app/SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
SYSTEM_SERVICE_FETCHERS的初始化为:
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap<String, ServiceFetcher<?>>();
static {
registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class, new CachedServiceFetcher<AccessibilityManager>() {
@Override
public AccessibilityManager createService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class, new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
.......
}
在SystemServiceRegistry 中初始化各个服务的manager对象, 在manager对象中来建立和对端的通信:
例如ActivityManager:
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
可以看到ActivityManager是在初始化时从ServiceManager中拿的ams的代理对象
frameworks/base/core/java/android/os/ServiceManager.java
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } sServiceManager = ServiceManagerNative .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); return sServiceManager; } public static IBinder getService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { return Binder.allowBlocking(getIServiceManager().getService(name)); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; }
从代码里面看, 他是先从sCache中拿, 拿不到的话在从sm(这里指的sm是指ServiceManager服务)中拿.
sCache的赋值处为:
public static void initServiceCache(Map<String, IBinder> cache) {
if (sCache.size() != 0) {
throw new IllegalStateException("setServiceCache may only be called once");
}
sCache.putAll(cache);
}
frameworks/base/core/java/android/app/ActivityThread.java
public final void bindApplication(String processName, ApplicationInfo appInfo,
┆ List<ProviderInfo> providers, ComponentName instrumentationName,
┆ ProfilerInfo profilerInfo, Bundle instrumentationArgs,
┆ IInstrumentationWatcher instrumentationWatcher,
┆ IUiAutomationConnection instrumentationUiConnection, int debugMode,
┆ boolean enableBinderTracking, boolean trackAllocation,
┆ boolean isRestrictedBackupMode, boolean persistent, Configuration config,
┆ CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
┆ String buildSerial) {
┆ if (services != null) {
┆ // Setup the service cache in the ServiceManager
┆ ServiceManager.initServiceCache(services);
┆ }
.....
可以看到是在bindApplication中,赋值的,而binderApplication是在进程启动时由 ams 回调过来的:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { if (app.instr != null) { thread.bindApplication(processName, appInfo, providers, ┆ app.instr.mClass, ┆ profilerInfo, app.instr.mArguments, ┆ app.instr.mWatcher, ┆ app.instr.mUiAutomationConnection, testMode, ┆ mBinderTransactionTrackingEnabled, enableTrackAllocation, ┆ isRestrictedBackupMode || !normalMode, app.persistent, ┆ new Configuration(getGlobalConfiguration()), app.compat, ┆ getCommonServicesLocked(app.isolated), ┆ mCoreSettingsObserver.getCoreSettingsLocked(), ┆ buildSerial); } else { thread.bindApplication(processName, appInfo, providers, null, profilerInfo, ┆ null, null, null, testMode, ┆ mBinderTransactionTrackingEnabled, enableTrackAllocation, ┆ isRestrictedBackupMode || !normalMode, app.persistent, ┆ new Configuration(getGlobalConfiguration()), app.compat, ┆ getCommonServicesLocked(app.isolated), ┆ mCoreSettingsObserver.getCoreSettingsLocked(), ┆ buildSerial); } ......
ams中是通过getCommonServicesLocked 来获取cache service的map 然后传入ActivityThread中的
private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { // Isolated processes won't get this optimization, so that we don't // violate the rules about which services they have access to. if (isolated) { ┆ if (mIsolatedAppBindArgs == null) { ┆ mIsolatedAppBindArgs = new HashMap<>(); ┆ mIsolatedAppBindArgs.put("package", ServiceManager.getService("package")); ┆ } ┆ return mIsolatedAppBindArgs; } if (mAppBindArgs == null) { ┆ mAppBindArgs = new HashMap<>(); ┆ // Setup the application init args ┆ mAppBindArgs.put("package", ServiceManager.getService("package")); ┆ mAppBindArgs.put("window", ServiceManager.getService("window")); ┆ mAppBindArgs.put(Context.ALARM_SERVICE, ┆ ┆ ServiceManager.getService(Context.ALARM_SERVICE)); } return mAppBindArgs; }
可以看到只有pms和wms 会通过 cache的方式获取, 其他 service 是使用进程间通信 通过sm 拿到的
createActivityContext
createSystemUiContext
createAppContext
createSystemContext
createApplicationContext
createPackageContext
createContextForSplit
…
…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。