getSystemService流程

getSystemService调用栈:

Activity—>ContextThemeWrapper—>ContextWrapper

@Override
public Object getSystemService(String name) {
		return mBase.getSystemService(name);
}

mBase 的赋值:

通过构造函数赋值

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 的赋值并不是通过构造函数赋值的

通过attachBaseContext赋值

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);
		}
}
通过attach 进行赋值

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();
		.......
}
performLaunchActivity 对Activity进行赋值

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);
		......
}
Context的创建createBaseContextForActivity

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;
}
createActivityContext 创建Context

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 也是同样的道理, 是基于 ContextImplcreateAppContext 方法创建的

getSystemService 的流程

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 拿到的

Context 的种类

createActivityContext
createSystemUiContext
createAppContext
createSystemContext
createApplicationContext
createPackageContext
createContextForSplit

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值