Android系统给我们提供了上百个服务,每一个服务都有一个服务中介类,例如WindowManager、ActivityManager等。
通常我们和系统服务进行交互都是通过服务中介来进行的。通过Context.getSystemService(String name)
我们可以获取系统服务,并在客户端封装成中介类,然后通过该中介类去获取相关的系统服务。那么到底系统服务和中介类是怎么获取的呢?
我们知道Context的实现类为ContextImpl,所以我们进入到ContextImpl的getSystemService(String name)
方法中:
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
这里执行了SystemServiceRegistry.getSystemService(String name)
方法,继续跟踪该方法:
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
可以看到系统服务中介类是从ServiceFetcher.getService(ContextImpl ctx)
方法获取的,而ServiceFetcher对象由SYSTEM_SERVICE_FETCHERS生成。SYSTEM_SERVICE_FETCHERS是一个HashMap,其Key为系统服务名,Value为ServiceFetcher对象。
那我们找一下SYSTEM_SERVICE_FETCHERS是什么时候被赋值的?在SystemServiceRegistry的registerService(String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher)
方法中我们找到了:
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
//在这类SYSTEM_SERVICE_FETCHERS被赋值
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
再看registerService方法是什么时候被调用的?可以找到在SystemServiceRegistry类的静态代码块中调用了registerService方法:
static {
registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
new CachedServiceFetcher<AccessibilityManager>() {
@Override
public AccessibilityManager createService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});
registerService(Context.CAPTIONING_SERVICE, CaptioningManager.class,
new CachedServiceFetcher<CaptioningManager>() {
@Override
public CaptioningManager createService(ContextImpl ctx) {
return new CaptioningManager(ctx);
}});
registerService(Context.ACCOUNT_SERVICE, AccountManager.class,
new CachedServiceFetcher<AccountManager>() {
@Override
public AccountManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.ACCOUNT_SERVICE);
IAccountManager service = IAccountManager.Stub.asInterface(b);
return new AccountManager(ctx, service);
}});
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
registerService(Context.ALARM_SERVICE, AlarmManager.class,
new CachedServiceFetcher<AlarmManager>() {
@Override
public AlarmManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service, ctx);
}});
...省略
}
这里多次调用了registerService方法,每一个registerService方法的参数中都new了一个ServiceFetcher对象。还记得上面我们说到的系统服务中介类是怎么来的吗?没错,就是通过ServiceFetcher对象的getService(ContextImpl ctx)
获取的。而ServiceFetcher是一个接口,其getService(ContextImpl ctx)
方法由子类来实现。在子类的实现方法中getService(ContextImpl ctx)
方法又调用了createService(ContextImpl ctx)
方法并返回,所以createService(ContextImpl ctx)
方法生成的对象就是我们需要获取的服务中介类。
最开始的时候我们提到,服务中介类只是对系统服务的一个封装。那就表明在ServiceFetcher对象的createService(ContextImpl ctx)
方法中肯定是能获取系统服务对象的。让我们看一个具体的例子:
registerService(Context.ALARM_SERVICE, AlarmManager.class,
new CachedServiceFetcher<AlarmManager>() {
@Override
public AlarmManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service, ctx);
}});
上面是获取闹钟系统服务的一个例子。
第一步:
通过ServiceManager.getServiceOrThrow(String name)
获取了服务端的Binder对象,而getServiceOrThrow最终调用的还是getService(String name)
方法:
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;
}
上面的代码告诉我们,如果有缓存则从缓存获取服务端的Binder对象,如果没有则调用getIServiceManager().getService(String name)获取服务端的Binder对象:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
从上面的代码可以看到获取服务端Binder对象也是通过Binder对象进行跨进程通信获取的(IServiceManager是一个Binder对象)。
第二步:
通过调用IAlarmManager.Stub.asInterface(Binder binder)
方法将第一步获取到的Binder对象转换成所需的系统服务对象。
这里说明一下,这个方法是区分进程的,如果客户端和服务端位于同一个进程,则返回服务端的Stub对象本身,否则返回的是系统封装后的Stub.proxy对象(该对象作为代理对象,与服务端进行通信并将数据返回给客户端)。
ServiceManager在这里起到的作用是对所有的系统服务进行管理,其提供了getService(String name)
,addService(String name)
,checkService(String name)
,listServices(String name)
等方法。
网友评论