现在的位置: 首页 > 综合 > 正文

ServiceManager分析

2017年12月24日 ⁄ 综合 ⁄ 共 2580字 ⁄ 字号 评论关闭

Service Manager 的工作就是登记功能。服务通过add_service方法将自己的名字和Binder 标识handle 登记在svclist 中。而服务请求者,通过check_service方法,通过服务名字在service list 中获取到service 相关联的Binder 的标识handle,通过这个Handle 作为请求包的目标地址发起请求。

通讯:IPC。Android 设计者在Linux内核中设计了一个叫做Binder 的设备文件,专门用来进行Android 的数据交换。从数据流来看Java 对象从Java 的VM 空间进入到C++空间进行了一次转换,并利用C++空间的函数将转换过的对象通过driver\binder 设备传递到服务进程,从而完成进程间的IPC。

(1)从JVM 空间传到c++空间,这个是靠JNI 使用ENV 来完成对象的映射过程。

(2)从c++空间传入内核Binder 设备,使用ProcessState 类完成工作。

(3) Service 从内核中Binder 设备读取数据。

ProcessState类中包含了通讯细节,利用open_binder打开Linux设备dev/binder,通过ioctrl建立的基本的通讯框架。利用上层传递下来的servicehandle来确定请求发送到那个ServiceBnbinderBpBinder的命名含义,Bn-代表Native,而Bp代表Proxy


在做服务请求时,Android建立一个新的Service Manager ProxyService
Manager Proxy
使用ContexObject作为BinderService Manager
Service
(服务端)进行通讯。

Android代码一般获取Service建立本地代理的用法如下:

              IXXX  mIxxx=IXXXInterface.Stub.asInterface(ServiceManager.getService("xxx"));

 例如:使用输入法服务:

               IInputMethodManager mImm=IInputMethodManager.Stub.asInterface(ServiceManager.getService("input_method"));

这些服务代理获取过程分解如下:

1通过调用GetContextObject调用获取设备上下对象。

           BinderInternal.getContextObject()           @BinderInteral.java

                  NATIVEJNI:getContextObject()               @android_util_Binder.cpp

                  Android_util_getConextObject               @android_util_Binder.cpp

ProcessState::self()->getCotextObject(0)              @processState.cpp

                      getStrongProxyForHandle(0)              

                                       NEW BpBinder(0)

 注意ProcessState::self()->getCotextObject(0)@processtate.cpp,就是该函数在进程空间建立ProcessState对象,打开了Binder设备dev/binder,并且传递了参数0,这个0代表了与Service
Manager
这个服务绑定。

2通过调用ServiceManager.asInterfaceContextObject)建立一个代理ServiceMangermRemote=ContextObject(Binder)

                   这样就建立起来ServiceManagerProxy通讯框架。

 (3)客户端通过调用ServiceManagergetService的方法建立一个相关的代理Binder

             ServiceMangerProxy.remote.transact(GET_SERVICE)

                                              IBinder=ret.ReadStrongBinder()    //这个就是JVM空间的代理Binder

           JNI Navite:android_os_Parcel_readStrongBinder()    @android_util_binder.cpp

                                                    Parcel->readStrongBinder()     @pacel.cpp

                                                                          unflatten_binder    @pacel.cpp

                                  getStrongProxyForHandle(flat_handle)

                                                       NEW BpBinder(flat_handle)    //这个就是底层c++空间新建的代理Binder

 

 Activity为了建立一个IPC,需要建立两个连接:访问Servicemanager Service的连接,具体XXX
Service
的代理对象IXXXXXXService的连接。这两个连接对应c++空间ProcessStateBpBinder。对IXXX的操作最后就是对BpBinder的操作。由于我们在写一个Service时,在一个Package中写了Service
Native
部分和Service Proxy部分,而NativeProxy都实现相同的接口:IXXX
Interface,
但是一个在服务端,一个在客服端。客户端调用的方式是使用remote->transact方法向Service发出请求,而在服务端的OnTransact中则是处理这些请求。所以在Android
Client
空间就看到这个效果:只需要调用代理对象方法就达到了对远程服务的调用目的,实际上这个调用路径好长好长。

【上篇】
【下篇】

抱歉!评论已关闭.