serviceManage

来源:互联网 发布:淘宝代销怎么退款 编辑:程序博客网 时间:2024/06/05 09:33

5.5  系统服务中的Binder对象

在应用程序编程时,经常使用getSystemService(String serviceName)方法获取一个系统服务,那么,这些系统服务的Binder引用是如何传递给客户端的呢?须知系统服务并不是通过startService()启动的。

getSystemService()函数的实现是在ContextImpl类中,该函数所返回的Service比较多,具体可参照源码。这些Service一般都由ServiceManager管理。

5.5.1  ServiceManager管理的服务

ServiceManager是一个独立进程,其作用如名称所示,管理各种系统服务,管理的逻辑如图5-5所示。

 图5-5  ServiceManager所管理的服务列表

ServiceManager本身也是一个Service,Framework提供了一个系统函数,可以获取该Service对应的Binder引用,那就是BinderInternal.getContextObject()。该静态函数返回ServiceManager后,就可以通过ServiceManager提供的方法获取其他系统Service的Binder引用。这种设计模式在日常生活中到处可见,ServiceManager就像是一个公司的总机,这个总机号码是公开的,系统中任何进程都可以使用BinderInternal.getContextObject()获取该总机的Binder对象,而当用户想联系公司中的其他人(服务)时,则要经过总机再获得分机号码。这种设计的好处是系统中仅暴露一个全局Binder引用,那就是ServiceManager,而其他系统服务则可以隐藏起来,从而有助于系统服务的扩展,以及调用系统服务的安全检查。其他系统服务在启动时,首先把自己的Binder对象传递给ServiceManager,即所谓的注册(addService)。

下面从代码实现来看以上逻辑。可以查看ContextImpl.getSystemService()中各种Service的具体获取方式,比如INPUT_METHOD_SERVICE,代码如下:

 

而InputMethodManager.getInstance(this)的关键代码如下:

 

即通过ServiceManager获取InputMethod Service对应的Binder对象b,然后再将该Binder对象作为IInputMethodManager.Stub.asInterface()的参数,返回一个IInputMethodManager的统一接口。

ServiceManager.getService()的代码如下:

 

即首先从sCache缓存中查看是否有对应的Binder对象,有则返回,没有则调用getIServiceManager().getService(name),第一个函数getIServiceManager()即用于返回系统中唯一的ServiceManager对应的Binder,其代码如下:

 

以上代码中,BinderInternal.getContextObject()静态函数即用于返回ServiceManager对应的全局Binder对象,该函数不需要任何参数,因为它的作用是固定的。从这个角度来看,这个函数的命名似乎更应该明确一些,比如,可以命名为getServiceManager()。

其他所有通过ServiceManager获取的系统服务的过程与以上基本类似,所不同的就是传递给ServiceManager的服务名称不同,因为ServiceManager正是按照服务的名称(String类型)来保存不同的Binder对象的。

关于使用addService()向ServiceManager中添加一个服务一般是在SystemService进程启动时完成的,具体见第9章中关于Framework启动过程的描述。


Manager和service的关系

程序通过serviceManager获得Manager,用户只能通过得到的Manager去访问对应的service不能直接访问。

总结

    其实和系统中的service通信和我们自己写的service通信是一样的,只不过我们直接写的直接返回Binder,通过Binder调用相应的方法。二系统service被ServiceManager管理者,当我们向ServiceManger相应的服务时,ServiceManager也会返回相应服务的Binder,但是这个Binder并不会直接返回客户端,而是给Manager这个代理,然后把Manager代理返回给客户端,客户端通过调用Manager中方法来调用Binder中的方法。




0 0