ServiceManager作为一个Binder(Service)的管理中心,是理解android中Binder通信原理的重要环节之一:
为了管理Binder(Service),需要如下几个函数:
- getService(String serviceName);
- checkService(String serviceName);
- addService(String serviceName);
- listService();
所以把如上的功能抽象为一个接口也就是IServiceManager,而此接口需要继承IInterface接口 //TODO 为何要继承它呢 ?
ServiceManager需要实现的这些功能,然而它没有继承这个IServiceManager而是持有着IServiceManager对象,任何的上述操作都会转交给IServiceManager对象去执行,也就是一个单纯的代理关系。
IServiceManager的初始化是调用了ServiceManagerNative.asInterface(BinderInternal.getContextObject());在这个asInterface()函数中需要注意了:
- 首先,getContextObject()这个函数获取的是应用的全局Context对象,可以把他看做是一个应用层跟底层Binder沟通的对象即可。—–> obj = context(Ibinder对象);
l - 其次在判断这个context对象不为空后去实例化IServiceManager对象,IServiceManager in = (IServiceManager)obj.queryLocalInterface(“android.os.IServiceManager”);那么在queryLocal(Binder?)过程发生了什么?
- 遍历所有实现了Binder对象(也就是查询Service)的接口的本地对象,如果本地没有一个serviceManager对象的话,选择下一步
- 如果本地没有任何ServiceManager对象,那么就执行new ServiceManagerProxy(obj). 那么这个代理是干嘛的呢?
- 当本地并没有一个IServiceManager的存在的话,就需要去创建一个ServiceManagerProxy对象,它实现了IServiceManager接口,作为一个内部类存在于ServiceManagerNative中。内部结构如下:
- 持有一个用户内存空间的binder对象,也就是记录下这个用户内存空间里的Binder对象(Service)。
- 初始化过程也是建立用户内存空间的IBinder对象 == mRemote 的联系
- getService(String serviceName):获取Service的流程:
- 初始化两个Parcel对象一个用来装想要获取的service的信息,一个作为存储来自查询结果(也就是一个IBinder对象)的。
- 通过用户内存空间上的IBinder对象的transact(GET_SERVICE_TRANSACTION, data, reply, 0)函数实现向真正的ServiceManager查询serviceName的过程。
- transact()函数的实现过程中让clientBinder进入到内核态挂起,binder驱动最终会唤醒server端的onTransact(int code, Parcel data, Parcel reply, int flags)函数。在server端执行的操作就是读取client端传入的参数,调用getService(string name)函数从而得到IBinder对象,装入到reply流中去。 (由此可见,ServiceManager本身也是一个特殊的Binder对象,查询serviceName都经过了client发送binder数据到binder驱动,驱动再次发送binder数据到managerService这整个流程.可以查看ServiceManagerNative这个类,本身是继承了Binder对象的。) //疑问 这个transact函数是如何确定一个serverBinder对象呢?也就是说binder驱动如何判定调用哪个binder的onTransact函数呢?
- 而实际上这个查询的过程可以通过一个缓存来解决HashMap
sCache。
- 而实际上这个查询的过程可以通过一个缓存来解决HashMap
- 最终的结果就是实现了ServiceManager中的IServiceManager对象 == new ServiceManagerProxy()对象的结果。完成client端的ServiceManager(也就是一个ServiceManagerProxy对象)的初始化过程。
- 首先,getContextObject()这个函数获取的是应用的全局Context对象,可以把他看做是一个应用层跟底层Binder沟通的对象即可。—–> obj = context(Ibinder对象);
而最重要的ServiceManagerNative的初始化工作只做了一件事儿:
- 调用Binder的attachInterface(this,descriptor)的工作,正式的把serviceManager对象跟Binder类中的IInterface mOwner绑定在一起。
- 而Binder类中的queryLocalInterface()函数返回的就是这个mOwner对象。
- 可见,此时的ServiceManagerNative就是一个server端的binder对象。