图解ServiceManager的获取服务过程(上)
概述
网上有很多关于ServiceManager
和Binder
的文章,但是老感觉理解起来不是那么顺畅,笔者基于Android 8.1系统源代码
,从最简单的获取服务开始了解Binder进程间通信
,由于篇幅原因,这里分开两部分来了解,上部分主要集中在Java层
,下部分主要集中在Native层
。
获取ServiceManager服务
我们以获取网络连接管理
为例:
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
connectivityManager.isActiveNetworkMetered();
上面的代码,大家应该都是非常熟悉了,那么我们是如何获取到这个ConnectivityManager
的呢?换句话说,获取服务的这个过程经历了哪些步骤呢?
笔者表达能力很一般,为了防止大家云里雾里,我提前先把这段用一个简单的时序图来整理一下:
过程分析
注意
:我们在Activity中
调用getService
的时候实际是调用父类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);
}
getBaseContext()
返回的实际是ContextImpl
,它是抽象类Context的子类实现
,ContextImpl
的实际调用如下:
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
我们发现是通过SystemServiceRegistry.getSystemService(this, name);
返回我们目标的服务,还得继续往下跟踪,找到系统源代码frameworks/base/core/java/android/app/SystemServiceRegistry.java
,我保留了几个比较关键的属性和方法
:
final class SystemServiceRegistry {
private static final String TAG = "SystemServiceRegistry";
......
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
private static int sServiceCacheSize;
// Not instantiable.
private SystemServiceRegistry() { }
static {
......
registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class,
new StaticApplicationContextServiceFetcher<ConnectivityManager>() {
@Override
public ConnectivityManager createService(Context context) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
return new ConnectivityManager(context, service);
}});
......
}
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
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);
}
static abstract interface ServiceFetcher<T> {
T getService(ContextImpl ctx);
}
......
}
可以看到,SystemServiceRegistry
这个类在static块
中完成了各种系统服务的注册,当我们获取服务的时候,其实是通过ServiceFetcher
匹配对应的服务名,即通过ServiceManager.getServiceOrThrow
这个方法返回我们目标的Manager
。
进入ServiceManager
接着我们来看frameworks/base/core/java/android/os/ServiceManager.java
的源码:
......
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
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;
}
public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
final IBinder binder = getService(name);
if (binder != null) {
return binder;
} else {
throw new ServiceNotFoundException(name);
}
}
通过上面的几段内容,我们已经跟踪到了ServiceManager
中来了,下面是获取服务的方法:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
frameworks/base/core/java/android/os/IServiceManager.java
public interface IServiceManager extends IInterface
{
......
public IBinder getService(String name) throws RemoteException;
......
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException;
......
}
这里就是frameworks/base/core/java/android/os/ServiceManagerNative.java
的具体实现:
public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
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);
}
public ServiceManagerNative()
{
attachInterface(this, descriptor);
}
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
{
try {
switch (code) {
case IServiceManager.GET_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = getService(name);
reply.writeStrongBinder(service);
return true;
}
......
case IServiceManager.ADD_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = data.readStrongBinder();
boolean allowIsolated = data.readInt() != 0;
addService(name, service, allowIsolated);
return true;
}
case IServiceManager.LIST_SERVICES_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String[] list = listServices();
reply.writeStringArray(list);
return true;
}
......
}
} catch (RemoteException e) {
}
return false;
}
public IBinder asBinder()
{
return this;
}
}
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
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;
}
......
private IBinder mRemote;
}
可以看到,我们最终还是调用到下层的ServiceManagerNative类中
,我们重点看这个getService的实现
,主要包含以下三部分:
1. 将所需参数通过Parcel
打包
2. 利用IBinder的transact
将请求发送出去,而不用去理会open,mmap
以及一堆的Binder协议中的命令
,这个IBinder
一定会在内部使用ProcessState
和IPCThreadState
来与Binder驱动
通信
3. 获取返回结果
下面这个关键方法
就封装了对远程Binder驱动
操作的一些通信协议,避免我们直接使用Binder协议
进行通信
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
思考
通过上面的过程分析我们对获取服务的过程
已经有一个基本的认识了,那么我们思考一下:
要知道我们获取服务最终还是通过Binder驱动
来进行通信,但是它毕竟不像我们调用同步方法那样直接返回,也没有一个回调方法,那么Android系统是如何保证同步获取服务的呢?
因为涉及到进程间通信,结果并不会立即获取,所以
Binder驱动
一定要先将调用者线程挂起
,直到有结果才会唤起调用者
,这样处理的好处就是调用者可以像进程内函数调用
一样去编写,而不用考虑同步异步的问题。
笔者会在下节native层
中进行分析
小结
可以看到,我们在Activity
中调用getService
获取服务,最终是通过ServiceManager
发起调用,然后通过ServiceManagerNative
返回的ServiceManagerProxy
代理类,实现与Binder驱动
的通信,返回对应的服务,笔者这里只是跟踪了Java层
中获取服务的过程
,下一节内容会以更多图文的形式来分析Native层
中获取服务
的过程。
参考
《Android系统源代码情景分析》
《深入理解android内核设计思想 第2版》