上文的篇幅很长,介绍了 ServiceManager 的启动流程,以 SurfaceFlinger 为例,介绍了它的简单启动流程和如何将自身添加到 ServiceManager 中。这篇了解下 Clent 端如何获取 Service。
ContextThemeWrapper
@Override
public Object getSystemService(String name) {
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
}
return mInflater;
}
return getBaseContext().getSystemService(name);
}
在 Activity 中我们调用 getSystemService,传入 Service 的名字,它会调到 getBaseContext().getSystemService(name);
getBaseContext() 在 ContextWrapper 中
ContextWrapper中
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
public Context getBaseContext() {
return mBase;
}
通过 attachBaseContext 将 Context 传入,这里需要 Activity 启动流程,这里不说这些,我们直接看下 Context 的实现类 ContextImpl 中的 getSystemService
ContextImpl中
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
SystemServiceRegistry中
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
static abstract interface ServiceFetcher<T> {
T getService(ContextImpl ctx);
}
其中 SystemServiceRegistry 里面的 SYSTEM_SERVICE_FETCHERS 相当于一个缓存,其存放的是 <String,ServiceFetcher> 键值对,String 表示服务名字,ServiceFetcher 持有服务对象或者是代理对象。
在 registerService 中将 serviceName put 到 SYSTEM_SERVICE_NAMES 中,将 serviceFetcher put 到 SYSTEM_SERVICE_FETCHERS 中。
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
new HashMap<Class<?>, String>();
当然在 SystemServiceRegistry 类中,有个静态代码块,注册了很多 SystemService 启动的 Service。这里就是调用了 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);
}});
//很多
}
当然原理也是通过 binder 去注册到 ServiceManager 中的,这里不在赘述,继续 getService
我们看一个 ServiceFetcher 实现类 CachedServiceFetcher
@Override
@SuppressWarnings("unchecked")
public final T getService(ContextImpl ctx) {
final Object[] cache = ctx.mServiceCache;
synchronized (cache) {
// Fetch or create the service.
Object service = cache[mCacheIndex];
if (service == null) {
try {
service = createService(ctx);
cache[mCacheIndex] = service;
} catch (ServiceNotFoundException e) {
onServiceNotFound(e);
}
}
return (T)service;
}
}
由以上的代码,我们可以看到返回服务对象的两种方法,一种是通过 new 或者 getInstance 直接返回服务对象,比如 ACCESIBILITY_SERVICE;而另一种是通过 IBinder 返回服务的代理对象,比如 ACCOUNT_SERVICE。第一种的服务我们就不再跟踪了。我们要研究的是第二种服务代理的对象,因为通过代码可以看出这种服务的对象本身不是在这里创建的,是通过 ServiceManager.getService 方法获取的,所以我们继续看下 ServiceManager.getService 方法。我们以 AlarmManager 为例。
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 方法返回 IBinder 类型的 b 对象,将 b 转为 IAlarmManager 类型,传入 AlarmManager 构造方法中返回 AlarmManager 对象。
ServiceManager.getServiceOrThrow
ServiceManager中
public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
final IBinder binder = getService(name);
if (binder != null) {
return binder;
} else {
throw new ServiceNotFoundException(name);
}
}
调用 getService 返回 binder
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;
}
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
缓存中取,没有 Binder.allowBlocking(getIServiceManager().getService(name)) 获取。
allowBlocking()
public static IBinder allowBlocking(IBinder binder) {
try {
if (binder instanceof BinderProxy) {
((BinderProxy) binder).mWarnOnBlocking = false;
} else if (binder != null
&& binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
Log.w(TAG, "Unable to allow blocking on interface " + binder);
}
} catch (RemoteException ignored) {
}
return binder;
}
这里判断返回的是代理对象还是自身对象,如果是代理对象将 mWarnOnBlocking 置为false。不是则检查 descriptor。
public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
if (mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;
}
queryLocalInterface 在第一篇中已经分析出来结论了,这里暂且假设不在同一进程,这里返回为 null。自然这个方法不会运行了,因为上面已经判断是否是 BinderProxy 了。
getIServiceManager()
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
获取 sServiceManager 也是需要 allowBlocking() 方法。
BinderInternal.getContextObject()
public static final native IBinder getContextObject();
实则调用到了 ProcessState::getContextObject
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
上篇已经提到了,返回一个 BpBinder。之后再 allowBlocking 中返回 BinderProxy
ServiceManagerNative.asInterface()
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
这里不多分析了,不懂得话看第一篇。这里创建一个 ServiceManagerProxy 类型的代理对象。
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}
这样就拿到 ServiceManager 的代理对象了。它的 getService 方法,
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
综上 Java 层的 ServiceManager 是一个 Aidl 示例,其他的系统服务也是如此通过 binder 获取。