ServiceManager
来源:互联网 发布:淘宝如何使用电子面单 编辑:程序博客网 时间:2024/06/05 17:31
ServiceManager层次基本如下,java空间的Service Manager类与Native空间的功能并不完全对应,java层的Service Manager类的实现最终是通过BinderProxy传递给Native层来完成的。
Service Manager存在的意义
1. Service Manager能集中管理系统内的所有服务,它能被施加权限控制,并不是任何进程都能注册服务的。
2. Service Manager支持通过字符串名称来查找对应的Service。
3. 由于各种原因的影响,Server进程可能生死无常。如果有了Service Manager做统一的管理,那么Client只要向Service Manager做查询,就能得到Server的最新信息。
1. Service Manager能集中管理系统内的所有服务,它能被施加权限控制,并不是任何进程都能注册服务的。
2. Service Manager支持通过字符串名称来查找对应的Service。
3. 由于各种原因的影响,Server进程可能生死无常。如果有了Service Manager做统一的管理,那么Client只要向Service Manager做查询,就能得到Server的最新信息。
1 ServiceManager启动
在init.rc中servicemanager是作为native服务启动的。
service servicemanager /system/bin/servicemanagerclass coreuser systemgroup systemcriticalonrestart restart zygoteonrestart restart mediaonrestart restart surfaceflingeronrestart restart drm
2 Native空间ServiceManager的工作内容
2.1 servicemanager#main
mian函数源码位置在frameworks/base/cmds/servicemanager/service_manager.c,如下:
int main(int argc, char **argv){struct binder_state *bs;//宏:#define BINDER_SERVICE_MANAGER ((void*)0)。表示ServiceManager对应的句柄为0,表面自己是服务器管理者。其他的Server进程句柄值都是大于0的。void *svcmgr = BINDER_SERVICE_MANAGER;//打开Binder设备,映射128K的内存地址空间bs = binder_open(128*1024);//告诉Binder驱动程序自己是Binder上下文管理者if (binder_become_context_manager(bs)) {ALOGE("cannot become context manager (%s)\n", strerror(errno));return -1;}//ServiceManager对应的句柄赋值svcmgr_handle = svcmgr;//进入一个无线循环,充当server角色,等待Client的请求binder_loop(bs, svcmgr_handler);return 0;}
从main函数中可以看出,它主要做了三件事情:
(1)打开/dev/binder设备,并在内存中映射128K的空间。
(1)打开/dev/binder设备,并在内存中映射128K的空间。
struct binder_state *binder_open(unsigned mapsize) { struct binder_state *bs; bs = malloc(sizeof(*bs)); if (!bs) { errno = ENOMEM; return 0; } bs->fd = open("/dev/binder", O_RDWR); if (bs->fd < 0) { fprintf(stderr,"binder: cannot open device (%s)\n", strerror(errno)); goto fail_open; } bs->mapsize = mapsize; bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); if (bs->mapped == MAP_FAILED) { fprintf(stderr,"binder: cannot map device (%s)\n", strerror(errno)); goto fail_map; } return bs; fail_map: close(bs->fd); fail_open: free(bs); return 0; }
(2)通知Binder设备,把自己变成context_manager
int binder_become_context_manager(struct binder_state *bs){ return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);}
(3)进入循环,不停的去读Binder设备,看是否有对service的请求,如果有的话,就去调用svcmgr_handler函数回调处理请求。
void binder_loop(struct binder_state *bs, binder_handler func) { int res; /* binder_write_read结构用来应用层和驱动层传递数据。 struct binder_write_read { signed long write_size; signed long write_consumed; unsigned long write_buffer; signed long read_size; signed long read_consumed; unsigned long read_buffer; }; */ struct binder_write_read bwr; unsigned readbuf[32]; bwr.write_size = 0; bwr.write_consumed = 0; bwr.write_buffer = 0; // 通知binder驱动,我要开始循环接受消息了。 readbuf[0] = BC_ENTER_LOOPER; binder_write(bs, readbuf, sizeof(unsigned)); // 开始循环接收数据 for (;;) { bwr.read_size = sizeof(readbuf); bwr.read_consumed = 0; bwr.read_buffer = (unsigned) readbuf; // 通过ioctl获得驱动中的数据 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); if (res < 0) { ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno)); break; } // 获得之后开始解析处理 res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func); if (res == 0) { ALOGE("binder_loop: unexpected reply?!\n"); break; } if (res < 0) { ALOGE("binder_loop: io error %d %s\n", res, strerror(errno)); break; } } }2.2 UML类图
3 java空间ServiceManger的工作内容
3.1 UML类图
(1)ServiceManager:通过getIServiceManager方法获取的是ServiceManagerProxy对象; ServiceManager的addService, getService实际工作都交由ServiceManagerProxy的相应方法来处理;
(2)ServiceManagerProxy:其成员变量mRemote指向BinderProxy对象,ServiceManagerProxy的addService, getService方法最终是交由mRemote来完成。
(3)ServiceManagerNative:其方法asInterface()返回的是ServiceManagerProxy对象,ServiceManager便是借助ServiceManagerNative类来找到ServiceManagerProxy;
(4)Binder:其成员变量mObject和方法execTransact()用于native方法
(5)BinderInternal:内部有一个GcWatcher类,用于处理和调试与Binder相关的垃圾回收。
(6)IBinder:接口中常量FLAG_ONEWAY:客户端利用binder跟服务端通信是阻塞式的,但如果设置了FLAG_ONEWAY,这成为非阻塞的调用方式,客户端能立即返回,服务端采用回调方式来通知客户端完成情况。另外IBinder接口有一个内部接口DeathDecipient(死亡通告)。
(3)ServiceManagerNative:其方法asInterface()返回的是ServiceManagerProxy对象,ServiceManager便是借助ServiceManagerNative类来找到ServiceManagerProxy;
(4)Binder:其成员变量mObject和方法execTransact()用于native方法
(5)BinderInternal:内部有一个GcWatcher类,用于处理和调试与Binder相关的垃圾回收。
(6)IBinder:接口中常量FLAG_ONEWAY:客户端利用binder跟服务端通信是阻塞式的,但如果设置了FLAG_ONEWAY,这成为非阻塞的调用方式,客户端能立即返回,服务端采用回调方式来通知客户端完成情况。另外IBinder接口有一个内部接口DeathDecipient(死亡通告)。
ServiceManager.addService方法
public static void addService(String name, IBinder service, boolean allowIsolated) { try { getIServiceManager().addService(name, service, allowIsolated); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); }}先看getIServiceManager
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }ServiceManager.getIServiceManager最终等价于new ServiceManagerProxy(new BinderProxy());framework层的ServiceManager的调用实际的工作确实交给远程接口ServiceManagerProxy的成员变量BinderProxy;而BinderProxy通过jni方式,最终会调用BpBinder对象;可见上层binder架构的核心功能基本都是靠native架构的服务来完成的。
4、Java空间与Native空间中ServiceManager的连接
从上面的分析来看,native空间与java空间的ServiceManager似乎没有什么联系,那java空间的ServiceManager代理是如何访问到native空间的ServiceManager服务呢?实际上,在Zygote进程中,先创建了虚拟机,然后注册了一系列的jni函数,其中有一个函数就是:REG_JNI(register_android_os_Binder),在这函数中会注册一个BinderInternal类,在这个类中有一个原生函数:
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },android_os_BinderInternal_getContextObject源码如下:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz){ sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//等价于 new BpBinder(0); return javaObjectForIBinder(env, b);}这里就相当于找到了binder链表中的ServiceManager的代理。当我们在使用ServiceManager的getIServiceManager()接口时,代码如下:
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager 等价于new ServiceManagerProxy(new BinderProxy()) sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }进而就可以call到binder驱动中,找到远程的ServiceManager的stub。
【如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!】
0 0
- ServiceManager
- ServiceManager
- ServiceManager & SystemService
- android----ServiceManager
- ServiceManager 学习
- ServiceManager分析
- ServiceManager总结
- killall servicemanager
- ServiceManager 学习
- ServiceManager入门
- ServiceManager.java
- start of servicemanager
- 【android】binder机制-servicemanager
- Android - Binder机制 - ServiceManager
- SystemServer vs ServiceManager
- Android binder -serviceManager
- android binder 机制 (ServiceManager)
- zf2分析:Zend\ServiceManager
- Oracle安装与启动
- Redux 入门教程(二):中间件与异步操作
- MFC CTreeView学习之右键菜单_获取选中节点的方式HitTest和GetSelectedItem的区别(二)
- Unity Shader 使用鼠标绘制自由多边形
- javaScript常用算法
- ServiceManager
- 浅谈:单例设计模式(Singleton)
- python Image库操作
- 解读Secondary NameNode的功能
- Linux下安装软件(rpm,yum)
- Java DAO浅析
- jar包置放在WEB-INF/lib下和通过build path导入的区别是什么
- vue中自定义组件(插件)
- 网络数据封装解析(IP,UDP,TCP)