ServiceManager

  • 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。
      • 最终的结果就是实现了ServiceManager中的IServiceManager对象 == new ServiceManagerProxy()对象的结果。完成client端的ServiceManager(也就是一个ServiceManagerProxy对象)的初始化过程。
    • 而最重要的ServiceManagerNative的初始化工作只做了一件事儿:

      • 调用Binder的attachInterface(this,descriptor)的工作,正式的把serviceManager对象跟Binder类中的IInterface mOwner绑定在一起。
      • 而Binder类中的queryLocalInterface()函数返回的就是这个mOwner对象。
      • 可见,此时的ServiceManagerNative就是一个server端的binder对象。