从java到C解析Binder机制
Binder机制是一种C/S结构,主要包括三部分,分别为Client、Server、ServiceManager。ServiceManager是谷歌设计的,它是一段简洁的C代码(位置在native/cmds/servicemanager/service_manager.c),主要是方便集中管理系统中的各种服务,也方便Client和Server查询系统中的服务信息。
我们首先来看一个跟ServiceManager很大关联的类,它就是IServiceManager类:
该类包括四个方法,名字就不重复了,通过这些方法可以注册服务、查询服务信息等,另外它还有一个enum枚举,enum包含与方法相对应的四个常量。查看源码我们可知enum常量的值为1,2,3,4。
enum {
GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
CHECK_SERVICE_TRANSACTION,
ADD_SERVICE_TRANSACTION,
LIST_SERVICES_TRANSACTION,
};
其中IBinder::FIRST_CALL_TRANSACTION的值为1,这里的取值是很重要的,因为他们分别对应ServiceManager(service_manager.c)中的enum常量:
enum {
SVC_MGR_GET_SERVICE = 1,
SVC_MGR_CHECK_SERVICE,
SVC_MGR_ADD_SERVICE,
SVC_MGR_LIST_SERVICES,
};
该enum在native/cmds/servicemanager/binder.h位置,service_manager.c程序引用了binder.h。这样C/S实现IServiceManager接口后,如果C/S传递GET_SERVICE_TRANSACTION参数,ServiceManager(service_manager.c)就能对应SVC_MGR_GET_SERVICE处理了,其他类似。
之所以开头就讲IServiceManager类,是因为我觉得从宏观上对C/S和ServiceManager的关系有一个大概的印象很重要,如下图所示:
如何看到这里你在好奇使用的是什么软件画图的,我郑重的推荐一下Gliffy画图软件,而且它有chrome插件,相比viso等软件更轻、更简单。
在上图IServiceManager和ServiceManager之间什么都没有画,那他们是如何通信的呢?其实他们是通过一种叫Binder设备进行通信的,这也是今天的主题,如果不了解设备的概念,建议查看linux的相关知识。我们将Binder设备加入可得到下图:
从上图我们知道了IServiceManager和ServiceManager可以通过Binder通信,但是还没有和C/S关联,我们加上C/S后来看看效果图,如下所示:
因为Client与binder通信在java层涉及的层次太多,我们主要分析Server与Binder的通信。